25 class OrderJointsByNewDepth {
28 return a->_new_parent_depth < b->_new_parent_depth;
38 _component_names(
"_",
"joint_")
40 _collection = collection;
53 for (si = _sliders.begin(); si != _sliders.end(); ++si) {
68 for (mi = _models.begin(); mi != _models.end(); ++mi) {
69 (*mi)._model_root->set_name(name);
87 m._model_index = model_index;
88 m._model_root = model_root;
89 m._egg_data = egg_data;
101 int max_num_frames = 0;
102 Components::const_iterator ci;
103 for (ci = _components.begin(); ci != _components.end(); ++ci) {
106 if (num_frames > 1) {
110 max_num_frames = std::max(max_num_frames, num_frames);
115 return max_num_frames;
124 Components::const_iterator ci;
125 for (ci = _components.begin(); ci != _components.end(); ++ci) {
128 if (frame_rate != 0.0) {
145 int max_num_frames = 0;
146 bool any_violations =
false;
147 Components::const_iterator ci;
148 for (ci = _components.begin(); ci != _components.end(); ++ci) {
151 if (num_frames > 1 && max_num_frames > 1 &&
152 max_num_frames != num_frames) {
155 any_violations =
true;
157 max_num_frames = std::max(max_num_frames, num_frames);
160 if (any_violations) {
162 for (ci = _components.begin(); ci != _components.end(); ++ci) {
165 if (num_frames > 1 && max_num_frames != num_frames) {
166 component->
extend_to(model_index, max_num_frames);
171 return !any_violations;
185 InvalidSet invalid_set;
188 Joints::const_iterator ji;
189 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
191 joint_data->do_begin_reparent();
196 _root_joint->do_begin_reparent();
201 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
204 if (joint_data->calc_new_parent_depth(chain)) {
205 nout <<
"Cycle detected in parent chain for " << joint_data->get_name()
210 sort(_joints.begin(), _joints.end(), OrderJointsByNewDepth());
215 Models::const_iterator mi;
216 for (mi = _models.begin(); mi != _models.end(); ++mi) {
218 int model_index = (*mi)._model_index;
220 nout <<
" computing " << (mi - _models.begin()) + 1
221 <<
" of " << _models.size()
222 <<
": " << (*mi)._egg_data->get_egg_filename()
223 <<
" (" << num_frames <<
" frames)\n";
224 for (
int f = 0; f < num_frames; f++) {
227 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
229 joint_data->do_begin_compute_reparent();
231 _root_joint->do_begin_compute_reparent();
235 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
237 if (!joint_data->do_compute_reparent(model_index, f, db)) {
239 invalid_set.insert(joint_data);
245 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
247 if (!joint_data->do_joint_rebuild(model_index, db)) {
248 invalid_set.insert(joint_data);
254 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
256 joint_data->do_finish_reparent();
263 InvalidSet::const_iterator si;
264 for (si = invalid_set.begin(); si != invalid_set.end(); ++si) {
268 if (joint_data->get_parent() !=
nullptr) {
269 nout <<
"Warning: reparenting " << joint_data->get_name()
271 if (joint_data->get_parent() == _root_joint) {
274 nout << joint_data->get_parent()->get_name();
276 nout <<
" results in an invalid transform.\n";
280 return invalid_set.empty();
297 Joints::const_iterator ji, jj;
298 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
304 for (jj = _joints.begin(); jj != _joints.end(); ++jj) {
306 if (possible_parent != joint_data && possible_parent != best_parent &&
307 !joint_data->is_new_ancestor(possible_parent)) {
310 if (score >= 0 && (best_score < 0 || score < best_score)) {
311 best_parent = possible_parent;
319 if (possible_parent != best_parent) {
321 if (score >= 0 && (best_score < 0 || score < best_score)) {
322 best_parent = possible_parent;
327 if (best_parent !=
nullptr &&
328 best_parent != joint_data->_parent) {
329 nout <<
"best parent for " << joint_data->get_name() <<
" is " 330 << best_parent->get_name() <<
"\n";
342 SlidersByName::const_iterator si;
343 si = _sliders_by_name.find(name);
344 if (si != _sliders_by_name.end()) {
357 SlidersByName::const_iterator si;
358 si = _sliders_by_name.find(name);
359 if (si != _sliders_by_name.end()) {
364 slider->set_name(name);
365 _sliders_by_name.insert(SlidersByName::value_type(name, slider));
366 _sliders.push_back(slider);
367 _components.push_back(slider);
381 size_t mj_frames = 0;
382 Models::const_iterator mi;
383 for (mi = _models.begin(); mi != _models.end(); ++mi) {
384 int model_index = (*mi)._model_index;
386 mj_frames += num_frames * _joints.size();
390 size_t mb_needed = ((mj_frames * 3 / 1024) *
sizeof(LMatrix4d)) / 1024;
399 void EggCharacterData::
400 write(std::ostream &out,
int indent_level)
const {
402 <<
"Character " << get_name() <<
":\n";
405 Sliders::const_iterator si;
406 for (si = _sliders.begin(); si != _sliders.end(); ++si) {
408 slider->write(out, indent_level + 2);
void reparent_to(EggJointData *new_parent)
Indicates an intention to change the parent of this joint to the indicated joint, or NULL to remove i...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_frames(int model_index) const
Returns the number of frames of animation for this particular component in the indicated model.
EggJointData * get_root_joint() const
Returns the root joint of the character hierarchy.
bool do_reparent()
Begins the process of restructuring the joint hierarchy according to the previous calls to reparent_t...
int get_num_frames(int model_index) const
Returns the number of frames of animation of the indicated model.
bool check_num_frames(int model_index)
Walks through each component and ensures that all have the same number of frames of animation (except...
void extend_to(int model_index, int num_frames) const
Extends the number of frames in the indicated model (presumably an animation table model) to the give...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This corresponds to a single morph slider control.
This is the primary interface into all the egg data, and the root of the egg file structure.
This is the base class of both EggJointData and EggSliderData.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class is used during joint optimization or restructuring to store the table of interim joint com...
EggSliderData * find_slider(const std::string &name) const
Returns the slider with the indicated name, or NULL if no slider has that name.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a set of characters, as read and collected from possibly several model and/or animation eg...
void choose_optimal_hierarchy()
Chooses the best possible parent joint for each of the joints in the hierarchy, based on the score co...
int score_reparent_to(EggJointData *new_parent, EggCharacterDb &db)
Computes a score >= 0 reflecting the similarity of the current joint's animation (in world space) to ...
EggSliderData * make_slider(const std::string &name)
Returns the slider matching the indicated name.
This is one node of a hierarchy of EggJointData nodes, each of which represents a single joint of the...
double get_frame_rate(int model_index) const
Returns the number of frames of animation for this particular component in the indicated model.
virtual EggSliderData * make_slider_data(EggCharacterData *char_data)
Allocates and returns a new EggSliderData structure for the given character.
A base class for things that may be directly added into the egg hierarchy.
This is our own Panda specialization on the default STL set.
void add_model(int model_index, EggNode *model_root, EggData *egg_data)
Indicates that the given model_index (with the indicated model_root) is associated with this characte...
double get_frame_rate(int model_index) const
Returns the stated frame rate of the specified model.
void rename_char(const std::string &name)
Renames all of the models in the character data to the indicated name.
size_t estimate_db_size() const
Returns the estimated amount of memory, in megabytes, that will be required to perform the do_reparen...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual EggJointData * make_joint_data(EggCharacterData *char_data)
Allocates and returns a new EggJointData structure for the given character.