open_toontown_panda3d/panda/src/chan/animControlCollection.cxx

273 lines
6.4 KiB
C++

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file animControlCollection.cxx
* @author drose
* @date 2000-02-22
*/
#include "animControlCollection.h"
using std::string;
/**
* Returns the AnimControl associated with the given name, or NULL if no such
* control has been associated.
*/
AnimControlCollection::
AnimControlCollection() {
_last_started_control = nullptr;
}
/**
*
*/
AnimControlCollection::
~AnimControlCollection() {
}
/**
* Associates the given AnimControl with this collection under the given name.
* The AnimControl will remain associated until a new AnimControl is
* associated with the same name later, or until unbind_anim() is called with
* this name.
*/
void AnimControlCollection::
store_anim(AnimControl *control, const string &name) {
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 {
// 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 = nullptr;
}
_controls[index]._control = control;
}
}
/**
* Returns the AnimControl associated with the given name, or NULL if no such
* control has been associated.
*/
AnimControl *AnimControlCollection::
find_anim(const string &name) const {
ControlsByName::const_iterator ci = _controls_by_name.find(name);
if (ci == _controls_by_name.end()) {
return nullptr;
}
size_t index = (*ci).second;
nassertr(index < _controls.size(), nullptr);
nassertr(_controls[index]._name == name, nullptr);
return _controls[index]._control;
}
/**
* Removes the AnimControl associated with the given name, if any. Returns
* true if an AnimControl was removed, false if there was no AnimControl with
* the indicated name.
*/
bool AnimControlCollection::
unbind_anim(const string &name) {
ControlsByName::iterator ci = _controls_by_name.find(name);
if (ci == _controls_by_name.end()) {
return false;
}
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 = nullptr;
}
_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;
}
/**
* Returns the number of AnimControls associated with this collection.
*/
int AnimControlCollection::
get_num_anims() const {
return _controls.size();
}
/**
* Returns the nth AnimControl associated with this collection.
*/
AnimControl *AnimControlCollection::
get_anim(int n) const {
nassertr(n >= 0 && n < (int)_controls.size(), nullptr);
return _controls[n]._control;
}
/**
* 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;
}
/**
* Disassociates all anims from this collection.
*/
void AnimControlCollection::
clear_anims() {
_controls.clear();
_controls_by_name.clear();
}
/**
* Starts all animations playing.
*/
void AnimControlCollection::
play_all() {
Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
(*ci)._control->play();
_last_started_control = (*ci)._control;
}
}
/**
* Starts all animations playing.
*/
void AnimControlCollection::
play_all(double from, double to) {
Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
(*ci)._control->play(from, to);
_last_started_control = (*ci)._control;
}
}
/**
* Starts all animations looping.
*/
void AnimControlCollection::
loop_all(bool restart) {
Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
(*ci)._control->loop(restart);
_last_started_control = (*ci)._control;
}
}
/**
* Starts all animations looping.
*/
void AnimControlCollection::
loop_all(bool restart, double from, double to) {
Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
(*ci)._control->loop(restart, from, to);
_last_started_control = (*ci)._control;
}
}
/**
* Stops all currently playing animations. Returns true if any animations
* were stopped, false if none were playing.
*/
bool AnimControlCollection::
stop_all() {
bool any = false;
Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
if ((*ci)._control->is_playing()) {
any = true;
(*ci)._control->stop();
}
}
return any;
}
/**
* Sets all animations to the indicated frame.
*/
void AnimControlCollection::
pose_all(double frame) {
Controls::const_iterator ci;
for (ci = _controls.begin(); ci != _controls.end(); ++ci) {
(*ci)._control->pose(frame);
_last_started_control = (*ci)._control;
}
}
/**
* Returns the name of the bound AnimControl currently playing, if any. If
* more than one AnimControl is currently playing, returns all of the names
* separated by spaces.
*/
string AnimControlCollection::
which_anim_playing() const {
string result;
Controls::const_iterator ci;
for (ci = _controls.begin();
ci != _controls.end();
++ci) {
if ((*ci)._control->is_playing()) {
if (!result.empty()) {
result += " ";
}
result += (*ci)._name;
}
}
return result;
}
/**
*
*/
void AnimControlCollection::
output(std::ostream &out) const {
out << _controls.size() << " anims.";
}
/**
*
*/
void AnimControlCollection::
write(std::ostream &out) const {
ControlsByName::const_iterator ci;
for (ci = _controls_by_name.begin();
ci != _controls_by_name.end();
++ci) {
out << (*ci).first << ": " << *_controls[(*ci).second]._control << "\n";
}
}