Selaa lähdekoodia

find_bound_joints

David Rose 17 vuotta sitten
vanhempi
sitoutus
99b905beb9

+ 22 - 2
panda/src/chan/animControl.cxx

@@ -81,6 +81,18 @@ setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: AnimControl::set_bound_joints
+//       Access: Public
+//  Description: Called to initialize the AnimControl with its array
+//               of bound_joints, before setup_anim() has completed.
+////////////////////////////////////////////////////////////////////
+void AnimControl::
+set_bound_joints(const BitArray &bound_joints) {
+  MutexHolder holder(_pending_lock);
+  _bound_joints = bound_joints;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: AnimControl::fail_anim
 //     Function: AnimControl::fail_anim
 //       Access: Public
 //       Access: Public
@@ -118,8 +130,16 @@ AnimControl::
 void AnimControl::
 void AnimControl::
 wait_pending() {
 wait_pending() {
   MutexHolder holder(_pending_lock);
   MutexHolder holder(_pending_lock);
-  while (_pending) {
-    _pending_cvar.wait();
+  if (_pending) {
+    // TODO: we should elevate the priority of the associated
+    // BindAnimRequest while we're waiting for it, so it will jump to
+    // the front of the queue.
+    chan_cat.info()
+      << "Blocking " << *Thread::get_current_thread() 
+      << " until " << get_name() << " is bound\n";
+    while (_pending) {
+      _pending_cvar.wait();
+    }
   }
   }
 }
 }
 
 

+ 1 - 0
panda/src/chan/animControl.h

@@ -44,6 +44,7 @@ public:
               double frame_rate, int num_frames);
               double frame_rate, int num_frames);
   void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
   void setup_anim(PartBundle *part, AnimBundle *anim, int channel_index,
                   const BitArray &bound_joints);
                   const BitArray &bound_joints);
+  void set_bound_joints(const BitArray &bound_joints);
   void fail_anim(PartBundle *part);
   void fail_anim(PartBundle *part);
 
 
 PUBLISHED:
 PUBLISHED:

+ 26 - 0
panda/src/chan/movingPartBase.cxx

@@ -289,3 +289,29 @@ bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
   PartGroup::bind_hierarchy(anim, channel_index, joint_index, 
   PartGroup::bind_hierarchy(anim, channel_index, joint_index, 
                             is_included, bound_joints, subset);
                             is_included, bound_joints, subset);
 }
 }
+
+////////////////////////////////////////////////////////////////////
+//     Function: MovingPartBase::find_bound_joints
+//       Access: Protected, Virtual
+//  Description: Similar to bind_hierarchy, but does not actually
+//               perform any binding.  All it does is compute the
+//               BitArray bount_joints according to the specified
+//               subset.  This is useful in preparation for
+//               asynchronous binding--in this case, we may need to
+//               know bound_joints immediately, without having to wait
+//               for the animation itself to load and bind.
+////////////////////////////////////////////////////////////////////
+void MovingPartBase::
+find_bound_joints(int &joint_index, bool is_included, BitArray &bound_joints,
+                  const PartSubset &subset) {
+  if (subset.matches_include(get_name())) {
+    is_included = true;
+  } else if (subset.matches_exclude(get_name())) {
+    is_included = false;
+  }
+
+  bound_joints.set_bit_to(joint_index, is_included);
+  ++joint_index;
+
+  PartGroup::find_bound_joints(joint_index, is_included, bound_joints, subset);
+}

+ 3 - 0
panda/src/chan/movingPartBase.h

@@ -72,6 +72,9 @@ protected:
                               int &joint_index, bool is_included, 
                               int &joint_index, bool is_included, 
                               BitArray &bound_joints,
                               BitArray &bound_joints,
                               const PartSubset &subset);
                               const PartSubset &subset);
+  virtual void find_bound_joints(int &joint_index, bool is_included, 
+                                 BitArray &bound_joints,
+                                 const PartSubset &subset);
 
 
   typedef pvector< PT(AnimChannelBase) > Channels;
   typedef pvector< PT(AnimChannelBase) > Channels;
   Channels _channels;
   Channels _channels;

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

@@ -354,6 +354,14 @@ load_bind_anim(Loader *loader, const Filename &filename,
   PT(AnimControl) control = 
   PT(AnimControl) control = 
     new AnimControl(basename, this, frame_rate, num_frames);
     new AnimControl(basename, this, frame_rate, num_frames);
 
 
+  if (!subset.is_include_empty()) {
+    // Figure out the actual subset of joints to be bound. 
+    int joint_index = 0;
+    BitArray bound_joints;
+    find_bound_joints(joint_index, false, bound_joints, subset);
+    control->set_bound_joints(bound_joints);
+  }
+
   PT(BindAnimRequest) request = 
   PT(BindAnimRequest) request = 
     new BindAnimRequest(filename, anim_options, control, 
     new BindAnimRequest(filename, anim_options, control, 
                         hierarchy_match_flags, subset);
                         hierarchy_match_flags, subset);

+ 27 - 0
panda/src/chan/partGroup.cxx

@@ -552,6 +552,33 @@ bind_hierarchy(AnimGroup *anim, int channel_index, int &joint_index,
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: PartGroup::find_bound_joints
+//       Access: Protected, Virtual
+//  Description: Similar to bind_hierarchy, but does not actually
+//               perform any binding.  All it does is compute the
+//               BitArray bount_joints according to the specified
+//               subset.  This is useful in preparation for
+//               asynchronous binding--in this case, we may need to
+//               know bound_joints immediately, without having to wait
+//               for the animation itself to load and bind.
+////////////////////////////////////////////////////////////////////
+void PartGroup::
+find_bound_joints(int &joint_index, bool is_included, BitArray &bound_joints,
+                  const PartSubset &subset) {
+  if (subset.matches_include(get_name())) {
+    is_included = true;
+  } else if (subset.matches_exclude(get_name())) {
+    is_included = false;
+  }
+
+  int part_num_children = get_num_children();
+  for (int i = 0; i < part_num_children; ++i) {
+    PartGroup *pc = get_child(i);
+    pc->find_bound_joints(joint_index, is_included, bound_joints, subset);
+  }
+}
+  
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: PartGroup::write_datagram
 //     Function: PartGroup::write_datagram
 //       Access: Public
 //       Access: Public

+ 3 - 0
panda/src/chan/partGroup.h

@@ -105,6 +105,9 @@ protected:
                               int &joint_index, bool is_included, 
                               int &joint_index, bool is_included, 
                               BitArray &bound_joints,
                               BitArray &bound_joints,
                               const PartSubset &subset);
                               const PartSubset &subset);
+  virtual void find_bound_joints(int &joint_index, bool is_included, 
+                                 BitArray &bound_joints,
+                                 const PartSubset &subset);
 
 
   typedef pvector< PT(PartGroup) > Children;
   typedef pvector< PT(PartGroup) > Children;
   Children _children;
   Children _children;