38 EggCharacterCollection::
39 EggCharacterCollection() {
40 _next_model_index = 0;
46 EggCharacterCollection::
47 ~EggCharacterCollection() {
48 Characters::iterator ci;
50 for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
68 _top_egg_nodes.clear();
70 if (!scan_hierarchy(egg)) {
74 int egg_index = _eggs.size();
76 EggInfo &egg_info = _eggs.back();
78 egg_info._first_model_index = 0;
82 TopEggNodesByName::iterator tni;
83 for (tni = _top_egg_nodes.begin(); tni != _top_egg_nodes.end(); ++tni) {
84 string character_name = (*tni).first;
89 TopEggNodes::iterator ti;
90 for (ti = top_nodes.begin(); ti != top_nodes.end(); ++ti) {
91 EggNode *model_root = (*ti).first;
92 ModelDescription &desc = (*ti).second;
94 int model_index = _next_model_index++;
95 if (egg_info._models.empty()) {
96 egg_info._first_model_index = model_index;
98 egg_info._models.push_back(model_root);
100 char_data->
add_model(model_index, model_root, egg);
101 nassertr(model_index == (
int)_characters_by_model_index.size(), -1);
102 _characters_by_model_index.push_back(char_data);
105 match_egg_nodes(char_data, root_joint, desc._top_nodes,
106 egg_index, model_index);
108 scan_for_morphs(model_root, model_index, char_data);
109 scan_for_sliders(model_root, model_index, char_data);
122 Characters::const_iterator ci;
123 for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
125 if (char_data->get_name() == character_name) {
173 Characters::iterator ci;
174 for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
176 if (char_data->get_name() == character_name) {
183 char_data->set_name(character_name);
184 _characters.push_back(char_data);
196 bool EggCharacterCollection::
197 scan_hierarchy(
EggNode *egg_node) {
198 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
200 if (group->get_dart_type() != EggGroup::DT_none) {
202 scan_for_top_joints(group, group, group->get_name());
206 }
else if (egg_node->
is_of_type(EggTable::get_class_type())) {
208 if (table->get_table_type() == EggTable::TT_bundle) {
210 scan_for_top_tables(table, table, table->get_name());
215 bool character_found =
false;
216 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
218 EggGroupNode::iterator gi;
219 for (gi = group->begin(); gi != group->end(); ++gi) {
220 if (scan_hierarchy(*gi)) {
221 character_found =
true;
226 return character_found;
233 void EggCharacterCollection::
235 const string &character_name) {
236 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
239 if (group->has_lod()) {
245 if (group->get_group_type() == EggGroup::GT_joint) {
247 ModelDescription &desc = _top_egg_nodes[character_name][model_root];
248 desc._root_node = model_root;
249 desc._top_nodes.push_back(group);
254 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
256 EggGroupNode::iterator gi;
257 for (gi = group->begin(); gi != group->end(); ++gi) {
258 scan_for_top_joints(*gi, model_root, character_name);
267 void EggCharacterCollection::
269 const string &character_name) {
272 EggGroupNode::iterator gi;
273 for (gi = bundle->begin(); gi != bundle->end(); ++gi) {
275 if (child->
is_of_type(EggTable::get_class_type())) {
277 if (table->get_name() ==
"<skeleton>") {
280 ModelDescription &desc = _top_egg_nodes[character_name][model_root];
281 desc._root_node = table;
283 EggGroupNode::iterator cgi;
284 for (cgi = table->begin(); cgi != table->end(); ++cgi) {
286 if (grandchild->
is_of_type(EggTable::get_class_type())) {
287 desc._top_nodes.push_back(grandchild);
299 void EggCharacterCollection::
300 scan_for_morphs(
EggNode *egg_node,
int model_index,
302 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
305 add_morph_back_pointers(prim, prim, model_index, char_data);
308 EggPrimitive::const_iterator vi;
309 for (vi = prim->begin(); vi != prim->end(); ++vi) {
312 add_morph_back_pointers(vertex, vertex, model_index, char_data);
313 add_morph_back_pointers_vertex(vertex, vertex, model_index, char_data);
315 EggMorphVertexList::const_iterator mvi;
316 for (mvi = vertex->_dxyzs.begin();
317 mvi != vertex->_dxyzs.end();
325 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
327 EggGroupNode::iterator gi;
328 for (gi = group->begin(); gi != group->end(); ++gi) {
329 scan_for_morphs(*gi, model_index, char_data);
338 void EggCharacterCollection::
339 scan_for_sliders(
EggNode *egg_node,
int model_index,
341 if (egg_node->
is_of_type(EggTable::get_class_type())) {
349 EggGroupNode::iterator gi;
350 for (gi = bundle->begin(); gi != bundle->end(); ++gi) {
352 if (child->
is_of_type(EggTable::get_class_type())) {
354 if (table->get_name() ==
"morph") {
358 EggGroupNode::iterator cgi;
359 for (cgi = table->begin(); cgi != table->end(); ++cgi) {
361 if (grandchild->
is_of_type(EggSAnimData::get_class_type())) {
375 void EggCharacterCollection::
378 EggMorphNormalList::const_iterator mni;
379 for (mni = attrib->_dnormals.begin();
380 mni != attrib->_dnormals.end();
386 EggMorphColorList::const_iterator mci;
387 for (mci = attrib->_drgbas.begin();
388 mci != attrib->_drgbas.end();
399 void EggCharacterCollection::
405 EggMorphTexCoordList::const_iterator mti;
406 for (mti = vert_uv->_duvs.begin();
407 mti != vert_uv->_duvs.end();
421 void EggCharacterCollection::
423 EggNodeList &egg_nodes,
int egg_index,
int model_index) {
428 if (joint_data->_children.empty()) {
431 EggNodeList::iterator ei;
432 for (ei = egg_nodes.begin(); ei != egg_nodes.end(); ++ei) {
435 joint_data->_children.push_back(data);
436 char_data->_joints.push_back(data);
437 char_data->_components.push_back(data);
438 data->_parent = joint_data;
439 data->_new_parent = joint_data;
440 found_egg_match(char_data, data, egg_node, egg_index, model_index);
447 EggNodeList extra_egg_nodes;
450 EggNodeList::iterator ei;
451 EggJointData::Children::iterator di;
453 ei = egg_nodes.begin();
454 di = joint_data->_children.begin();
456 while (ei != egg_nodes.end() && di != joint_data->_children.end()) {
460 if (egg_node->get_name() < data->get_name()) {
462 extra_egg_nodes.push_back(egg_node);
465 }
else if (data->get_name() < egg_node->get_name()) {
467 extra_data.push_back(data);
472 found_egg_match(char_data, data, egg_node, egg_index, model_index);
478 while (ei != egg_nodes.end()) {
482 extra_egg_nodes.push_back(egg_node);
486 while (di != joint_data->_children.end()) {
490 extra_data.push_back(data);
494 if (!extra_egg_nodes.empty()) {
499 EggNodeList more_egg_nodes;
501 for (ei = extra_egg_nodes.begin(); ei != extra_egg_nodes.end(); ++ei) {
503 bool matched =
false;
504 for (di = extra_data.begin(); di != extra_data.end(); ++di) {
506 if (data->matches_name(egg_node->get_name())) {
507 found_egg_match(char_data, data, egg_node, egg_index, model_index);
508 extra_data.erase(di);
516 more_egg_nodes.push_back(egg_node);
519 extra_egg_nodes.swap(more_egg_nodes);
522 if (!extra_egg_nodes.empty()) {
524 if (extra_egg_nodes.size() == extra_data.size()) {
527 for (i = 0; i < extra_egg_nodes.size(); i++) {
528 EggNode *egg_node = extra_egg_nodes[i];
530 found_egg_match(char_data, data, egg_node, egg_index, model_index);
535 EggNodeList::iterator ei;
536 for (ei = extra_egg_nodes.begin(); ei != extra_egg_nodes.end(); ++ei) {
539 joint_data->_children.push_back(data);
540 char_data->_joints.push_back(data);
541 char_data->_components.push_back(data);
542 data->_parent = joint_data;
543 data->_new_parent = joint_data;
544 found_egg_match(char_data, data, egg_node, egg_index, model_index);
551 sort(joint_data->_children.begin(), joint_data->_children.end(),
559 void EggCharacterCollection::
561 EggNode *egg_node,
int egg_index,
int model_index) {
563 joint_data->
add_name(egg_node->get_name(), char_data->_component_names);
565 egg_node->set_name(joint_data->get_name());
568 if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
573 EggNodeList egg_nodes;
578 if (egg_node->
is_of_type(EggGroup::get_class_type())) {
580 EggGroupNode::iterator gi;
581 for (gi = group_node->begin(); gi != group_node->end(); ++gi) {
583 if (child->
is_of_type(EggGroup::get_class_type())) {
585 if (group->get_group_type() == EggGroup::GT_joint) {
586 egg_nodes.push_back(group);
593 EggGroupNode::iterator gi;
594 for (gi = group_node->begin(); gi != group_node->end(); ++gi) {
596 if (child->
is_of_type(EggTable::get_class_type())) {
598 if (!(table->get_name() ==
"xform")) {
599 egg_nodes.push_back(table);
605 if (!egg_nodes.empty()) {
606 match_egg_nodes(char_data, joint_data, egg_nodes,
607 egg_index, model_index);
618 nassertv(i >= 0 && i < (
int)_characters.size());
621 if (char_data->get_name() != name) {
630 void EggCharacterCollection::
631 write(std::ostream &out,
int indent_level)
const {
632 Characters::const_iterator ci;
634 for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
636 char_data->write(out, indent_level);
651 check_errors(std::ostream &out,
bool force_initial_rest_frame) {
652 Characters::const_iterator ci;
653 for (ci = _characters.begin(); ci != _characters.end(); ++ci) {
656 for (
int j = 0; j < num_joints; j++) {
659 if (force_initial_rest_frame) {
661 out <<
"Forced rest frames the same for " << joint_data->get_name()
664 out <<
"Warning: rest frames for " << joint_data->get_name()
671 for (
int mi = 0; mi < num_models; mi++) {
674 out <<
"Warning: animation from "
676 <<
" had an inconsistent number of frames.\n";