Browse Source

new joint freezing on a low level

Zachary Pavlov 18 years ago
parent
commit
81b52e39c5

+ 73 - 0
panda/src/chan/animGroup.cxx

@@ -233,6 +233,79 @@ make_child_dynamic(const string &name) {
   return (AnimGroup *)NULL;
   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
 //     Function: AnimGroup::get_value_type
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 2 - 1
panda/src/chan/animGroup.h

@@ -52,7 +52,7 @@ PUBLISHED:
   AnimGroup *find_child(const string &name) const;
   AnimGroup *find_child(const string &name) const;
 
 
   AnimGroup *make_child_dynamic(const string &name);
   AnimGroup *make_child_dynamic(const string &name);
-
+  void make_child_fixed(const string &name, const LMatrix4f &mat);
 public:
 public:
   virtual TypeHandle get_value_type() const;
   virtual TypeHandle get_value_type() const;
 
 
@@ -85,6 +85,7 @@ protected:
   void fillin(DatagramIterator& scan, BamReader* manager);
   void fillin(DatagramIterator& scan, BamReader* manager);
 
 
 private:
 private:
+  typedef pvector< string > frozenJoints;
   int _num_children;
   int _num_children;
 
 
 public:
 public:

+ 14 - 0
panda/src/chan/partBundle.I

@@ -207,3 +207,17 @@ get_control_effect(AnimControl *control) const {
   return do_get_control_effect(control, cdata);
   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);
+}

+ 5 - 0
panda/src/chan/partBundle.cxx

@@ -213,6 +213,11 @@ bind_anim(AnimBundle *anim, int hierarchy_match_flags,
       return NULL;
       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)) {
   if (!check_hierarchy(anim, NULL, hierarchy_match_flags)) {
     return NULL;
     return NULL;

+ 11 - 0
panda/src/chan/partBundle.h

@@ -109,6 +109,8 @@ PUBLISHED:
   INLINE int get_num_nodes() const;
   INLINE int get_num_nodes() const;
   INLINE PartBundleNode *get_node(int n) const;
   INLINE PartBundleNode *get_node(int n) const;
 
 
+  INLINE void freeze_joint(string jointName, LMatrix4f transform) const;
+
   void clear_control_effects();
   void clear_control_effects();
   INLINE void set_control_effect(AnimControl *control, float effect);
   INLINE void set_control_effect(AnimControl *control, float effect);
   INLINE float get_control_effect(AnimControl *control) const;
   INLINE float get_control_effect(AnimControl *control) const;
@@ -194,6 +196,15 @@ public:
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
 
 
+  typedef struct {
+    string name;
+    LMatrix4f transform;
+  } JointTransform ;
+
+  typedef pvector< JointTransform > JointTransformList;
+  
+  JointTransformList _frozen_joints;
+
   friend class PartBundleNode;
   friend class PartBundleNode;
   friend class MovingPartBase;
   friend class MovingPartBase;
   friend class MovingPartMatrix;
   friend class MovingPartMatrix;