allow iterating through anims in AnimControlCollection

This commit is contained in:
David Rose 2004-10-14 18:23:18 +00:00
parent 13be5ce398
commit 2a017f1288
6 changed files with 113 additions and 29 deletions

View File

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

View File

@ -25,6 +25,16 @@
TypeHandle AnimBundleNode::_type_handle; 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 // Function: AnimBundleNode::safe_to_flatten
// Access: Public, Virtual // Access: Public, Virtual

View File

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

View File

@ -51,14 +51,26 @@ AnimControlCollection::
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
store_anim(AnimControl *control, const string &name) { store_anim(AnimControl *control, const string &name) {
Controls::iterator ci = _controls.find(name); ControlsByName::iterator ci = _controls_by_name.find(name);
if (ci == _controls.end()) {
_controls.insert(Controls::value_type(name, control)); 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 { } 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; _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:: AnimControl *AnimControlCollection::
find_anim(const string &name) const { find_anim(const string &name) const {
Controls::const_iterator ci = _controls.find(name); ControlsByName::const_iterator ci = _controls_by_name.find(name);
if (ci == _controls.end()) { if (ci == _controls_by_name.end()) {
return (AnimControl *)NULL; 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:: bool AnimControlCollection::
unbind_anim(const string &name) { unbind_anim(const string &name) {
Controls::iterator ci = _controls.find(name); ControlsByName::iterator ci = _controls_by_name.find(name);
if (ci == _controls.end()) { if (ci == _controls_by_name.end()) {
return false; 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; _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; return true;
} }
@ -109,6 +140,30 @@ get_num_anims() const {
return _controls.size(); 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 // Function: AnimControlCollection::clear_anims
// Access: Published // Access: Published
@ -117,6 +172,7 @@ get_num_anims() const {
void AnimControlCollection:: void AnimControlCollection::
clear_anims() { clear_anims() {
_controls.clear(); _controls.clear();
_controls_by_name.clear();
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -128,7 +184,7 @@ void AnimControlCollection::
play_all() { play_all() {
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++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) { play_all(int from, int to) {
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++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) { loop_all(bool restart) {
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++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) { loop_all(bool restart, int from, int to) {
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++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; bool any = false;
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) { for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
if ((*ci).second->is_playing()) { if ((*ci)._control->is_playing()) {
any = true; any = true;
(*ci).second->stop(); (*ci)._control->stop();
} }
} }
@ -201,7 +257,7 @@ void AnimControlCollection::
pose_all(int frame) { pose_all(int frame) {
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++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; string result;
Controls::const_iterator ci; Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) { for (ci = _controls.begin();
if ((*ci).second->is_playing()) { ci != _controls.end();
++ci) {
if ((*ci)._control->is_playing()) {
if (!result.empty()) { if (!result.empty()) {
result += " "; result += " ";
} }
result += (*ci).first; result += (*ci)._name;
} }
} }
@ -247,8 +305,10 @@ output(ostream &out) const {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void AnimControlCollection:: void AnimControlCollection::
write(ostream &out) const { write(ostream &out) const {
Controls::const_iterator ci; ControlsByName::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) { for (ci = _controls_by_name.begin();
out << (*ci).first << ": " << *(*ci).second << "\n"; ci != _controls_by_name.end();
++ci) {
out << (*ci).first << ": " << *_controls[(*ci).second]._control << "\n";
} }
} }

View File

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

View File

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