Browse Source

allow iterating through anims in AnimControlCollection

David Rose 21 years ago
parent
commit
2a017f1288

+ 1 - 2
panda/src/chan/animBundleNode.I

@@ -46,8 +46,7 @@ AnimBundleNode() : PandaNode("") {
 //     Function: AnimBundleNode::Copy Constructor
 //       Access: Protected
 //  Description: Use make_copy() or copy_subgraph() to copy one of
-//               these.  Copying a AnimBundleNode will always force a
-//               deep copy of the PartGroup hierarchy.
+//               these.
 ////////////////////////////////////////////////////////////////////
 INLINE AnimBundleNode::
 AnimBundleNode(const AnimBundleNode &copy) :

+ 10 - 0
panda/src/chan/animBundleNode.cxx

@@ -25,6 +25,16 @@
 TypeHandle AnimBundleNode::_type_handle;
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: AnimBundleNode::make_copy
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+PandaNode *AnimBundleNode::
+make_copy() const {
+  return new AnimBundleNode(*this);
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AnimBundleNode::safe_to_flatten
 //       Access: Public, Virtual

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

@@ -41,6 +41,7 @@ protected:
   INLINE AnimBundleNode(const AnimBundleNode &copy);
 
 public:
+  virtual PandaNode *make_copy() const;
   virtual bool safe_to_flatten() const;
 
 PUBLISHED:

+ 85 - 25
panda/src/chan/animControlCollection.cxx

@@ -51,14 +51,26 @@ AnimControlCollection::
 ////////////////////////////////////////////////////////////////////
 void AnimControlCollection::
 store_anim(AnimControl *control, const string &name) {
-  Controls::iterator ci = _controls.find(name);
-  if (ci == _controls.end()) {
-    _controls.insert(Controls::value_type(name, control));
+  ControlsByName::iterator ci = _controls_by_name.find(name);
+
+  if (ci == _controls_by_name.end()) {
+    // Insert a new control.
+    size_t index = _controls.size();
+    ControlDef cdef;
+    cdef._control = control;
+    cdef._name = name;
+    _controls.push_back(cdef);
+    _controls_by_name.insert(ControlsByName::value_type(name, index));
+
   } else {
-    if (_last_started_control == (*ci).second) {
+    // Replace an existing control.
+    size_t index = (*ci).second;
+    nassertv(index < _controls.size());
+    nassertv(_controls[index]._name == name);
+    if (_last_started_control == _controls[index]._control) {
       _last_started_control = (AnimControl *)NULL;
     }
-    (*ci).second = control;
+    _controls[index]._control = control;
   }
 }
 
@@ -70,11 +82,14 @@ store_anim(AnimControl *control, const string &name) {
 ////////////////////////////////////////////////////////////////////
 AnimControl *AnimControlCollection::
 find_anim(const string &name) const {
-  Controls::const_iterator ci = _controls.find(name);
-  if (ci == _controls.end()) {
+  ControlsByName::const_iterator ci = _controls_by_name.find(name);
+  if (ci == _controls_by_name.end()) {
     return (AnimControl *)NULL;
   }
-  return (*ci).second;
+  size_t index = (*ci).second;
+  nassertr(index < _controls.size(), NULL);
+  nassertr(_controls[index]._name == name, NULL);
+  return _controls[index]._control;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -87,14 +102,30 @@ find_anim(const string &name) const {
 ////////////////////////////////////////////////////////////////////
 bool AnimControlCollection::
 unbind_anim(const string &name) {
-  Controls::iterator ci = _controls.find(name);
-  if (ci == _controls.end()) {
+  ControlsByName::iterator ci = _controls_by_name.find(name);
+  if (ci == _controls_by_name.end()) {
     return false;
   }
-  if (_last_started_control == (*ci).second) {
+  size_t index = (*ci).second;
+  nassertr(index < _controls.size(), false);
+  nassertr(_controls[index]._name == name, false);
+
+  if (_last_started_control == _controls[index]._control) {
     _last_started_control = (AnimControl *)NULL;
   }
-  _controls.erase(ci);
+  _controls_by_name.erase(ci);
+
+  _controls.erase(_controls.begin() + index);
+
+  // Now slide all the index numbers down.
+  for (ci = _controls_by_name.begin();
+       ci != _controls_by_name.end();
+       ++ci) {
+    if ((*ci).second > index) {
+      (*ci).second--;
+    }
+  }
+
   return true;
 }
 
@@ -109,6 +140,30 @@ get_num_anims() const {
   return _controls.size();
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: AnimControlCollection::get_anim
+//       Access: Published
+//  Description: Returns the nth AnimControl associated with
+//               this collection.
+////////////////////////////////////////////////////////////////////
+AnimControl *AnimControlCollection::
+get_anim(int n) const {
+  nassertr(n >= 0 && n < (int)_controls.size(), NULL);
+  return _controls[n]._control;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AnimControlCollection::get_anim_name
+//       Access: Published
+//  Description: Returns the name of the nth AnimControl associated
+//               with this collection.
+////////////////////////////////////////////////////////////////////
+string AnimControlCollection::
+get_anim_name(int n) const {
+  nassertr(n >= 0 && n < (int)_controls.size(), string());
+  return _controls[n]._name;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: AnimControlCollection::clear_anims
 //       Access: Published
@@ -117,6 +172,7 @@ get_num_anims() const {
 void AnimControlCollection::
 clear_anims() {
   _controls.clear();
+  _controls_by_name.clear();
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -128,7 +184,7 @@ void AnimControlCollection::
 play_all() {
   Controls::const_iterator ci;
   for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    (*ci).second->play();
+    (*ci)._control->play();
   }
 }
 
@@ -141,7 +197,7 @@ void AnimControlCollection::
 play_all(int from, int to) {
   Controls::const_iterator ci;
   for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    (*ci).second->play(from, to);
+    (*ci)._control->play(from, to);
   }
 }
 
@@ -154,7 +210,7 @@ void AnimControlCollection::
 loop_all(bool restart) {
   Controls::const_iterator ci;
   for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    (*ci).second->loop(restart);
+    (*ci)._control->loop(restart);
   }
 }
 
@@ -167,7 +223,7 @@ void AnimControlCollection::
 loop_all(bool restart, int from, int to) {
   Controls::const_iterator ci;
   for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    (*ci).second->loop(restart, from, to);
+    (*ci)._control->loop(restart, from, to);
   }
 }
 
@@ -183,9 +239,9 @@ stop_all() {
   bool any = false;
   Controls::const_iterator ci;
   for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    if ((*ci).second->is_playing()) {
+    if ((*ci)._control->is_playing()) {
       any = true;
-      (*ci).second->stop();
+      (*ci)._control->stop();
     }
   }
 
@@ -201,7 +257,7 @@ void AnimControlCollection::
 pose_all(int frame) {
   Controls::const_iterator ci;
   for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    (*ci).second->pose(frame);
+    (*ci)._control->pose(frame);
   }
 }
 
@@ -218,12 +274,14 @@ which_anim_playing() const {
   string result;
 
   Controls::const_iterator ci;
-  for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    if ((*ci).second->is_playing()) {
+  for (ci = _controls.begin(); 
+       ci != _controls.end(); 
+       ++ci) {
+    if ((*ci)._control->is_playing()) {
       if (!result.empty()) {
         result += " ";
       }
-      result += (*ci).first;
+      result += (*ci)._name;
     }
   }
 
@@ -247,8 +305,10 @@ output(ostream &out) const {
 ////////////////////////////////////////////////////////////////////
 void AnimControlCollection::
 write(ostream &out) const {
-  Controls::const_iterator ci;
-  for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
-    out << (*ci).first << ": " << *(*ci).second << "\n";
+  ControlsByName::const_iterator ci;
+  for (ci = _controls_by_name.begin(); 
+       ci != _controls_by_name.end(); 
+       ++ci) {
+    out << (*ci).first << ": " << *_controls[(*ci).second]._control << "\n";
   }
 }

+ 12 - 1
panda/src/chan/animControlCollection.h

@@ -48,6 +48,8 @@ PUBLISHED:
   bool unbind_anim(const string &name);
 
   int get_num_anims() const;
+  AnimControl *get_anim(int n) const;
+  string get_anim_name(int n) const;
   void clear_anims();
 
   INLINE void set_stop_event(const CPT_Event &stop_event);
@@ -87,8 +89,17 @@ PUBLISHED:
   void write(ostream &out) const;
 
 private:
-  typedef pmap<string,  PT(AnimControl) > Controls;
+  class ControlDef {
+  public:
+    string _name;
+    PT(AnimControl) _control;
+  };
+  typedef pvector<ControlDef> Controls;
   Controls _controls;
+
+  typedef pmap<string, size_t> ControlsByName;
+  ControlsByName _controls_by_name;
+
   CPT_Event _stop_event;
   AnimControl *_last_started_control;
 };

+ 4 - 1
panda/src/chan/auto_bind.cxx

@@ -58,7 +58,10 @@ bind_anims(const PartNodes &parts, const AnimNodes &anims,
 
       PT(AnimControl) control =
         part->bind_anim(anim, hierarchy_match_flags);
-      string name = anim->get_name();
+      string name = (*ani)->get_name();
+      if (name.empty()) {
+        name = anim->get_name();
+      }
       if (control != (AnimControl *)NULL) {
         if (controls.find_anim(name) != (AnimControl *)NULL) {
           // That name's already used; synthesize another one.