xFileAnimationSet.cxx 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Filename: xFileAnimationSet.cxx
  2. // Created by: drose (02Oct04)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) Carnegie Mellon University. All rights reserved.
  8. //
  9. // All use of this software is subject to the terms of the revised BSD
  10. // license. You should have received a copy of this license along
  11. // with this source code in a file named "LICENSE."
  12. //
  13. ////////////////////////////////////////////////////////////////////
  14. #include "xFileAnimationSet.h"
  15. #include "xFileToEggConverter.h"
  16. #include "config_xfile.h"
  17. #include "eggGroup.h"
  18. #include "eggTable.h"
  19. #include "eggData.h"
  20. #include "eggXfmSAnim.h"
  21. #include "dcast.h"
  22. ////////////////////////////////////////////////////////////////////
  23. // Function: XFileAnimationSet::Constructor
  24. // Access: Public
  25. // Description:
  26. ////////////////////////////////////////////////////////////////////
  27. XFileAnimationSet::
  28. XFileAnimationSet() {
  29. _frame_rate = 0.0;
  30. }
  31. ////////////////////////////////////////////////////////////////////
  32. // Function: XFileAnimationSet::Destructor
  33. // Access: Public
  34. // Description:
  35. ////////////////////////////////////////////////////////////////////
  36. XFileAnimationSet::
  37. ~XFileAnimationSet() {
  38. }
  39. ////////////////////////////////////////////////////////////////////
  40. // Function: XFileAnimationSet::create_hierarchy
  41. // Access: Public
  42. // Description: Sets up the hierarchy of EggTables corresponding to
  43. // this AnimationSet.
  44. ////////////////////////////////////////////////////////////////////
  45. bool XFileAnimationSet::
  46. create_hierarchy(XFileToEggConverter *converter) {
  47. // Egg animation tables start off with one Table entry, enclosing a
  48. // Bundle entry.
  49. EggTable *table = new EggTable(get_name());
  50. converter->get_egg_data()->add_child(table);
  51. EggTable *bundle = new EggTable(converter->_char_name);
  52. table->add_child(bundle);
  53. bundle->set_table_type(EggTable::TT_bundle);
  54. // Then the Bundle contains a "<skeleton>" entry, which begins the
  55. // animation table hierarchy.
  56. EggTable *skeleton = new EggTable("<skeleton>");
  57. bundle->add_child(skeleton);
  58. // Fill in the rest of the hierarchy with empty tables.
  59. mirror_table(converter, converter->get_dart_node(), skeleton);
  60. // Now populate those empty tables with the frame data.
  61. JointData::const_iterator ji;
  62. for (ji = _joint_data.begin(); ji != _joint_data.end(); ++ji) {
  63. const string &joint_name = (*ji).first;
  64. const FrameData &table = (*ji).second;
  65. EggXfmSAnim *anim_table = get_table(joint_name);
  66. if (anim_table == (EggXfmSAnim *)NULL) {
  67. xfile_cat.warning()
  68. << "Frame " << joint_name << ", named by animation data, not defined.\n";
  69. } else {
  70. // If we have animation data, apply it.
  71. FrameEntries::const_iterator fi;
  72. for (fi = table._entries.begin(); fi != table._entries.end(); ++fi) {
  73. anim_table->add_data((*fi).get_mat(table._flags));
  74. }
  75. anim_table->optimize();
  76. }
  77. }
  78. // Put some data in the empty tables also.
  79. Tables::iterator ti;
  80. for (ti = _tables.begin(); ti != _tables.end(); ++ti) {
  81. EggXfmSAnim *anim_table = (*ti).second._table;
  82. EggGroup *joint = (*ti).second._joint;
  83. if (anim_table->empty() && joint != (EggGroup *)NULL) {
  84. // If there's no animation data, assign the rest transform.
  85. anim_table->add_data(joint->get_transform3d());
  86. }
  87. anim_table->optimize();
  88. if (_frame_rate != 0.0) {
  89. anim_table->set_fps(_frame_rate);
  90. }
  91. }
  92. return true;
  93. }
  94. ////////////////////////////////////////////////////////////////////
  95. // Function: XFileAnimationSet::get_table
  96. // Access: Public
  97. // Description: Returns the table associated with the indicated joint
  98. // name.
  99. ////////////////////////////////////////////////////////////////////
  100. EggXfmSAnim *XFileAnimationSet::
  101. get_table(const string &joint_name) const {
  102. Tables::const_iterator ti;
  103. ti = _tables.find(joint_name);
  104. if (ti != _tables.end()) {
  105. return (*ti).second._table;
  106. }
  107. return NULL;
  108. }
  109. ////////////////////////////////////////////////////////////////////
  110. // Function: XFileAnimationSet::create_frame_data
  111. // Access: Public
  112. // Description: Returns a reference to a new FrameData table
  113. // corresponding to the indicated joint.
  114. ////////////////////////////////////////////////////////////////////
  115. XFileAnimationSet::FrameData &XFileAnimationSet::
  116. create_frame_data(const string &joint_name) {
  117. return _joint_data[joint_name];
  118. }
  119. ////////////////////////////////////////////////////////////////////
  120. // Function: XFileAnimationSet::mirror_table
  121. // Access: Private
  122. // Description: Builds up a new set of EggTable nodes, as a
  123. // mirror of the existing set of EggGroup (joint)
  124. // nodes, and saves each new table in the _tables
  125. // record.
  126. ////////////////////////////////////////////////////////////////////
  127. void XFileAnimationSet::
  128. mirror_table(XFileToEggConverter *converter,
  129. EggGroup *model_node, EggTable *anim_node) {
  130. EggGroupNode::iterator gi;
  131. for (gi = model_node->begin(); gi != model_node->end(); ++gi) {
  132. EggNode *child = (*gi);
  133. if (child->is_of_type(EggGroup::get_class_type())) {
  134. EggGroup *group = DCAST(EggGroup, child);
  135. if (group->get_group_type() == EggGroup::GT_joint) {
  136. // When we come to a <Joint>, create a new Table for it.
  137. EggTable *new_table = new EggTable(group->get_name());
  138. anim_node->add_child(new_table);
  139. CoordinateSystem cs =
  140. converter->get_egg_data()->get_coordinate_system();
  141. EggXfmSAnim *xform = new EggXfmSAnim("xform", cs);
  142. new_table->add_child(xform);
  143. xform->set_fps(converter->_frame_rate);
  144. TablePair &table_pair = _tables[group->get_name()];
  145. table_pair._table = xform;
  146. table_pair._joint = group;
  147. // Now recurse.
  148. mirror_table(converter, group, new_table);
  149. } else {
  150. // If we come to an ordinary <Group>, skip past it.
  151. mirror_table(converter, group, anim_node);
  152. }
  153. }
  154. }
  155. }