From 81b52e39c5dc9599eb8a0c4a0301a376c79ee614 Mon Sep 17 00:00:00 2001 From: Zachary Pavlov Date: Thu, 31 May 2007 23:44:39 +0000 Subject: [PATCH] new joint freezing on a low level --- panda/src/chan/animGroup.cxx | 73 +++++++++++++++++++++++++++++++++++ panda/src/chan/animGroup.h | 3 +- panda/src/chan/partBundle.I | 14 +++++++ panda/src/chan/partBundle.cxx | 5 +++ panda/src/chan/partBundle.h | 11 ++++++ 5 files changed, 105 insertions(+), 1 deletion(-) diff --git a/panda/src/chan/animGroup.cxx b/panda/src/chan/animGroup.cxx index 0f2930397e..51b45930cd 100644 --- a/panda/src/chan/animGroup.cxx +++ b/panda/src/chan/animGroup.cxx @@ -233,6 +233,79 @@ make_child_dynamic(const string &name) { return (AnimGroup *)NULL; } + +//////////////////////////////////////////////////////////////////// +// Function: AnimGroup::make_child_fixed +// Access: Public +// Description: Finds the indicated child and replaces it with an +// AnimChannelMatrixFixed with the specified transform +// This may be called before binding the animation to a +// character to replace certain joints with +// frozen ones. +// +// Returns NULL if the named child cannot be found. +//////////////////////////////////////////////////////////////////// +void AnimGroup:: +void make_child_fixed(const string &name, const LMatrix4f &mat) { + Children::iterator ci; + for (ci = _children.begin(); ci != _children.end(); ++ci) { + AnimGroup *child = (*ci); + if (child->get_name() == name) { + AnimGroup *new_child = NULL; + + if (child->is_of_type(AnimChannelMatrix::get_class_type())) { + AnimChannelMatrix *mchild = DCAST(AnimChannelMatrix, child); + AnimChannelMatrixFixed *new_mchild = + new AnimChannelMatrixFixed(this, name, mat); + new_child = new_mchild; + } + + if (new_child != (AnimGroup *)NULL) { + new_child->_children.swap(child->_children); + nassertr(_children.back() == new_child, NULL); + + // The new child was appended to the end of our children list + // by its constructor. Reposition it to replace the original + // child. + + // I would like to use these lines, but for some reason it + // crashes: + /* + { + (*ci) = new_child; + _children.pop_back(); + } + */ + + // But this longer way of achieving the same result works + // instead: + { + Children::iterator nci; + Children new_children; + for (nci = _children.begin(); nci != _children.end(); ++nci) { + if ((*nci) == child) { + new_children.push_back(new_child); + } else if ((*nci) != new_child) { + new_children.push_back(*nci); + } + } + new_children.swap(_children); + } + + return new_child; + } + } + AnimGroup *result = child->make_child_fixed(name, mat); + if (result != (AnimGroup *)NULL) { + return result; + } + } + + return (AnimGroup *)NULL; +} + + + //////////////////////////////////////////////////////////////////// // Function: AnimGroup::get_value_type // Access: Public, Virtual diff --git a/panda/src/chan/animGroup.h b/panda/src/chan/animGroup.h index a8ef0a0d5f..bed59271e6 100644 --- a/panda/src/chan/animGroup.h +++ b/panda/src/chan/animGroup.h @@ -52,7 +52,7 @@ PUBLISHED: AnimGroup *find_child(const string &name) const; AnimGroup *make_child_dynamic(const string &name); - + void make_child_fixed(const string &name, const LMatrix4f &mat); public: virtual TypeHandle get_value_type() const; @@ -85,6 +85,7 @@ protected: void fillin(DatagramIterator& scan, BamReader* manager); private: + typedef pvector< string > frozenJoints; int _num_children; public: diff --git a/panda/src/chan/partBundle.I b/panda/src/chan/partBundle.I index f37ce246bf..ebbc3b8954 100644 --- a/panda/src/chan/partBundle.I +++ b/panda/src/chan/partBundle.I @@ -207,3 +207,17 @@ get_control_effect(AnimControl *control) const { return do_get_control_effect(control, cdata); } +//////////////////////////////////////////////////////////////////// +// Function: PartBundle::freeze_joint +// Access: Protected +// Description: stores away a joint freeze for bind time +//////////////////////////////////////////////////////////////////// +INLINE void PartBundle:: +freeze_joint(string jointName, LMatrix4f transform) const +{ + JointTransform jt; + jt.name=jointName; + jt.transform=transform; + + _frozen_joints.push_back(jt); +} diff --git a/panda/src/chan/partBundle.cxx b/panda/src/chan/partBundle.cxx index be01436b2b..f0a0f3e1f0 100644 --- a/panda/src/chan/partBundle.cxx +++ b/panda/src/chan/partBundle.cxx @@ -213,6 +213,11 @@ bind_anim(AnimBundle *anim, int hierarchy_match_flags, return NULL; } } + + JointTransformList::iterator jti; + for (jti = _frozen_joints.begin(); jti != _frozen_joints.end(); ++jti) { + anim->make_child_fixed((*jti).name, (*jti).transform); + } if (!check_hierarchy(anim, NULL, hierarchy_match_flags)) { return NULL; diff --git a/panda/src/chan/partBundle.h b/panda/src/chan/partBundle.h index 72df4373f0..1c083540b8 100644 --- a/panda/src/chan/partBundle.h +++ b/panda/src/chan/partBundle.h @@ -109,6 +109,8 @@ PUBLISHED: INLINE int get_num_nodes() const; INLINE PartBundleNode *get_node(int n) const; + INLINE void freeze_joint(string jointName, LMatrix4f transform) const; + void clear_control_effects(); INLINE void set_control_effect(AnimControl *control, float effect); INLINE float get_control_effect(AnimControl *control) const; @@ -194,6 +196,15 @@ public: private: static TypeHandle _type_handle; + typedef struct { + string name; + LMatrix4f transform; + } JointTransform ; + + typedef pvector< JointTransform > JointTransformList; + + JointTransformList _frozen_joints; + friend class PartBundleNode; friend class MovingPartBase; friend class MovingPartMatrix;