Panda3D
|
00001 // Filename: xFileAnimationSet.cxx 00002 // Created by: drose (02Oct04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "xFileAnimationSet.h" 00016 #include "xFileToEggConverter.h" 00017 #include "config_xfile.h" 00018 #include "eggGroup.h" 00019 #include "eggTable.h" 00020 #include "eggData.h" 00021 #include "eggXfmSAnim.h" 00022 #include "dcast.h" 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: XFileAnimationSet::Constructor 00026 // Access: Public 00027 // Description: 00028 //////////////////////////////////////////////////////////////////// 00029 XFileAnimationSet:: 00030 XFileAnimationSet() { 00031 _frame_rate = 0.0; 00032 } 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: XFileAnimationSet::Destructor 00036 // Access: Public 00037 // Description: 00038 //////////////////////////////////////////////////////////////////// 00039 XFileAnimationSet:: 00040 ~XFileAnimationSet() { 00041 } 00042 00043 //////////////////////////////////////////////////////////////////// 00044 // Function: XFileAnimationSet::create_hierarchy 00045 // Access: Public 00046 // Description: Sets up the hierarchy of EggTables corresponding to 00047 // this AnimationSet. 00048 //////////////////////////////////////////////////////////////////// 00049 bool XFileAnimationSet:: 00050 create_hierarchy(XFileToEggConverter *converter) { 00051 // Egg animation tables start off with one Table entry, enclosing a 00052 // Bundle entry. 00053 EggTable *table = new EggTable(get_name()); 00054 converter->get_egg_data()->add_child(table); 00055 EggTable *bundle = new EggTable(converter->_char_name); 00056 table->add_child(bundle); 00057 bundle->set_table_type(EggTable::TT_bundle); 00058 00059 // Then the Bundle contains a "<skeleton>" entry, which begins the 00060 // animation table hierarchy. 00061 EggTable *skeleton = new EggTable("<skeleton>"); 00062 bundle->add_child(skeleton); 00063 00064 // Fill in the rest of the hierarchy with empty tables. 00065 mirror_table(converter, converter->get_dart_node(), skeleton); 00066 00067 // Now populate those empty tables with the frame data. 00068 JointData::const_iterator ji; 00069 for (ji = _joint_data.begin(); ji != _joint_data.end(); ++ji) { 00070 const string &joint_name = (*ji).first; 00071 const FrameData &table = (*ji).second; 00072 00073 EggXfmSAnim *anim_table = get_table(joint_name); 00074 if (anim_table == (EggXfmSAnim *)NULL) { 00075 xfile_cat.warning() 00076 << "Frame " << joint_name << ", named by animation data, not defined.\n"; 00077 } else { 00078 // If we have animation data, apply it. 00079 FrameEntries::const_iterator fi; 00080 for (fi = table._entries.begin(); fi != table._entries.end(); ++fi) { 00081 anim_table->add_data((*fi).get_mat(table._flags)); 00082 } 00083 anim_table->optimize(); 00084 } 00085 } 00086 00087 // Put some data in the empty tables also. 00088 Tables::iterator ti; 00089 for (ti = _tables.begin(); ti != _tables.end(); ++ti) { 00090 EggXfmSAnim *anim_table = (*ti).second._table; 00091 EggGroup *joint = (*ti).second._joint; 00092 if (anim_table->empty() && joint != (EggGroup *)NULL) { 00093 // If there's no animation data, assign the rest transform. 00094 anim_table->add_data(joint->get_transform3d()); 00095 } 00096 anim_table->optimize(); 00097 if (_frame_rate != 0.0) { 00098 anim_table->set_fps(_frame_rate); 00099 } 00100 } 00101 00102 return true; 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: XFileAnimationSet::get_table 00107 // Access: Public 00108 // Description: Returns the table associated with the indicated joint 00109 // name. 00110 //////////////////////////////////////////////////////////////////// 00111 EggXfmSAnim *XFileAnimationSet:: 00112 get_table(const string &joint_name) const { 00113 Tables::const_iterator ti; 00114 ti = _tables.find(joint_name); 00115 if (ti != _tables.end()) { 00116 return (*ti).second._table; 00117 } 00118 return NULL; 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: XFileAnimationSet::create_frame_data 00123 // Access: Public 00124 // Description: Returns a reference to a new FrameData table 00125 // corresponding to the indicated joint. 00126 //////////////////////////////////////////////////////////////////// 00127 XFileAnimationSet::FrameData &XFileAnimationSet:: 00128 create_frame_data(const string &joint_name) { 00129 return _joint_data[joint_name]; 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: XFileAnimationSet::mirror_table 00134 // Access: Private 00135 // Description: Builds up a new set of EggTable nodes, as a 00136 // mirror of the existing set of EggGroup (joint) 00137 // nodes, and saves each new table in the _tables 00138 // record. 00139 //////////////////////////////////////////////////////////////////// 00140 void XFileAnimationSet:: 00141 mirror_table(XFileToEggConverter *converter, 00142 EggGroup *model_node, EggTable *anim_node) { 00143 EggGroupNode::iterator gi; 00144 for (gi = model_node->begin(); gi != model_node->end(); ++gi) { 00145 EggNode *child = (*gi); 00146 if (child->is_of_type(EggGroup::get_class_type())) { 00147 EggGroup *group = DCAST(EggGroup, child); 00148 if (group->get_group_type() == EggGroup::GT_joint) { 00149 // When we come to a <Joint>, create a new Table for it. 00150 EggTable *new_table = new EggTable(group->get_name()); 00151 anim_node->add_child(new_table); 00152 CoordinateSystem cs = 00153 converter->get_egg_data()->get_coordinate_system(); 00154 EggXfmSAnim *xform = new EggXfmSAnim("xform", cs); 00155 new_table->add_child(xform); 00156 xform->set_fps(converter->_frame_rate); 00157 TablePair &table_pair = _tables[group->get_name()]; 00158 table_pair._table = xform; 00159 table_pair._joint = group; 00160 00161 // Now recurse. 00162 mirror_table(converter, group, new_table); 00163 00164 } else { 00165 // If we come to an ordinary <Group>, skip past it. 00166 mirror_table(converter, group, anim_node); 00167 } 00168 } 00169 } 00170 }