From 2a017f12884ff4da404cc205fb197cb9fa4aec58 Mon Sep 17 00:00:00 2001 From: David Rose Date: Thu, 14 Oct 2004 18:23:18 +0000 Subject: [PATCH] allow iterating through anims in AnimControlCollection --- panda/src/chan/animBundleNode.I | 3 +- panda/src/chan/animBundleNode.cxx | 10 +++ panda/src/chan/animBundleNode.h | 1 + panda/src/chan/animControlCollection.cxx | 110 +++++++++++++++++------ panda/src/chan/animControlCollection.h | 13 ++- panda/src/chan/auto_bind.cxx | 5 +- 6 files changed, 113 insertions(+), 29 deletions(-) diff --git a/panda/src/chan/animBundleNode.I b/panda/src/chan/animBundleNode.I index e35b7e2812..54bea1986c 100644 --- a/panda/src/chan/animBundleNode.I +++ b/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 ©) : diff --git a/panda/src/chan/animBundleNode.cxx b/panda/src/chan/animBundleNode.cxx index 1fcfa39d89..eb140490e1 100644 --- a/panda/src/chan/animBundleNode.cxx +++ b/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 diff --git a/panda/src/chan/animBundleNode.h b/panda/src/chan/animBundleNode.h index 9fcd0ae20f..49c88007ce 100644 --- a/panda/src/chan/animBundleNode.h +++ b/panda/src/chan/animBundleNode.h @@ -41,6 +41,7 @@ protected: INLINE AnimBundleNode(const AnimBundleNode ©); public: + virtual PandaNode *make_copy() const; virtual bool safe_to_flatten() const; PUBLISHED: diff --git a/panda/src/chan/animControlCollection.cxx b/panda/src/chan/animControlCollection.cxx index 814bde7116..0fad4dd6dc 100644 --- a/panda/src/chan/animControlCollection.cxx +++ b/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"; } } diff --git a/panda/src/chan/animControlCollection.h b/panda/src/chan/animControlCollection.h index e9e6b68d2b..7b5349c557 100644 --- a/panda/src/chan/animControlCollection.h +++ b/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 Controls; + class ControlDef { + public: + string _name; + PT(AnimControl) _control; + }; + typedef pvector Controls; Controls _controls; + + typedef pmap ControlsByName; + ControlsByName _controls_by_name; + CPT_Event _stop_event; AnimControl *_last_started_control; }; diff --git a/panda/src/chan/auto_bind.cxx b/panda/src/chan/auto_bind.cxx index 008739c86d..160411358f 100644 --- a/panda/src/chan/auto_bind.cxx +++ b/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.