Panda3D
|
00001 // Filename: eggCharacterData.cxx 00002 // Created by: drose (23Feb01) 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 "eggCharacterData.h" 00016 #include "eggCharacterCollection.h" 00017 #include "eggCharacterDb.h" 00018 #include "eggJointData.h" 00019 #include "eggSliderData.h" 00020 #include "indent.h" 00021 00022 #include <algorithm> 00023 00024 // An STL function object to sort the joint list in order from highest 00025 // to lowest in the new hierarchy. Used in do_reparent(). 00026 class OrderJointsByNewDepth { 00027 public: 00028 bool operator()(const EggJointData *a, const EggJointData *b) const { 00029 return a->_new_parent_depth < b->_new_parent_depth; 00030 } 00031 }; 00032 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: EggCharacterData::Constructor 00036 // Access: Public 00037 // Description: 00038 //////////////////////////////////////////////////////////////////// 00039 EggCharacterData:: 00040 EggCharacterData(EggCharacterCollection *collection) : 00041 _component_names("_", "joint_") 00042 { 00043 _collection = collection; 00044 _root_joint = _collection->make_joint_data(this); 00045 // The fictitious root joint is not added to the _components list. 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: EggCharacterData::Destructor 00050 // Access: Public, Virtual 00051 // Description: 00052 //////////////////////////////////////////////////////////////////// 00053 EggCharacterData:: 00054 ~EggCharacterData() { 00055 delete _root_joint; 00056 00057 Sliders::iterator si; 00058 for (si = _sliders.begin(); si != _sliders.end(); ++si) { 00059 EggSliderData *slider = (*si); 00060 delete slider; 00061 } 00062 } 00063 00064 //////////////////////////////////////////////////////////////////// 00065 // Function: EggCharacterData::rename_char 00066 // Access: Public 00067 // Description: Renames all of the models in the character data to 00068 // the indicated name. This is the name that is used to 00069 // identify unique skeleton hierarchies; if you set two 00070 // different models to the same name, they will be 00071 // loaded together as if they are expected to have the 00072 // same skeleton hierarchy. 00073 //////////////////////////////////////////////////////////////////// 00074 void EggCharacterData:: 00075 rename_char(const string &name) { 00076 Models::iterator mi; 00077 for (mi = _models.begin(); mi != _models.end(); ++mi) { 00078 (*mi)._model_root->set_name(name); 00079 } 00080 00081 set_name(name); 00082 } 00083 00084 //////////////////////////////////////////////////////////////////// 00085 // Function: EggCharacterData::add_model 00086 // Access: Public 00087 // Description: Indicates that the given model_index (with the 00088 // indicated model_root) is associated with this 00089 // character. This is normally called by the 00090 // EggCharacterCollection class as new models are 00091 // discovered. 00092 // 00093 // A "model" here is either a character model (or one 00094 // LOD of a character model), or a character animation 00095 // file: in either case, a hierarchy of joints. 00096 //////////////////////////////////////////////////////////////////// 00097 void EggCharacterData:: 00098 add_model(int model_index, EggNode *model_root, EggData *egg_data) { 00099 Model m; 00100 m._model_index = model_index; 00101 m._model_root = model_root; 00102 m._egg_data = egg_data; 00103 _models.push_back(m); 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: EggCharacterData::get_num_frames 00108 // Access: Public 00109 // Description: Returns the number of frames of animation of the 00110 // indicated model. This is more reliable than asking a 00111 // particular joint or slider of the animation for its 00112 // number of frames, since a particular joint may have 00113 // only 1 frame (if it is unanimated), even though the 00114 // overall animation has many frames. 00115 //////////////////////////////////////////////////////////////////// 00116 int EggCharacterData:: 00117 get_num_frames(int model_index) const { 00118 int max_num_frames = 0; 00119 Components::const_iterator ci; 00120 for (ci = _components.begin(); ci != _components.end(); ++ci) { 00121 EggComponentData *component = (*ci); 00122 int num_frames = component->get_num_frames(model_index); 00123 if (num_frames > 1) { 00124 // We have a winner. Assume all other components will be 00125 // similar. 00126 return num_frames; 00127 } 00128 max_num_frames = max(max_num_frames, num_frames); 00129 } 00130 00131 // Every component had either 1 frame or 0 frames. Return the 00132 // maximum of these. 00133 return max_num_frames; 00134 } 00135 00136 //////////////////////////////////////////////////////////////////// 00137 // Function: EggCharacterData::get_frame_rate 00138 // Access: Public 00139 // Description: Returns the stated frame rate of the specified model. 00140 // Similar to get_num_frames(). 00141 //////////////////////////////////////////////////////////////////// 00142 double EggCharacterData:: 00143 get_frame_rate(int model_index) const { 00144 Components::const_iterator ci; 00145 for (ci = _components.begin(); ci != _components.end(); ++ci) { 00146 EggComponentData *component = (*ci); 00147 double frame_rate = component->get_frame_rate(model_index); 00148 if (frame_rate != 0.0) { 00149 // We have a winner. Assume all other components will be 00150 // similar. 00151 return frame_rate; 00152 } 00153 } 00154 00155 return 0.0; 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: EggCharacterData::check_num_frames 00160 // Access: Public 00161 // Description: Walks through each component and ensures that all 00162 // have the same number of frames of animation (except 00163 // for those that contain 0 or 1 frames, of course). 00164 // Returns true if all are valid, false if there is a 00165 // discreprency (in which case the shorter component are 00166 // extended). 00167 //////////////////////////////////////////////////////////////////// 00168 bool EggCharacterData:: 00169 check_num_frames(int model_index) { 00170 int max_num_frames = 0; 00171 bool any_violations = false; 00172 Components::const_iterator ci; 00173 for (ci = _components.begin(); ci != _components.end(); ++ci) { 00174 EggComponentData *component = (*ci); 00175 int num_frames = component->get_num_frames(model_index); 00176 if (num_frames > 1 && max_num_frames > 1 && 00177 max_num_frames != num_frames) { 00178 // If we have two different opinions about the number of frames 00179 // (other than 0 or 1), we have a discrepency. This is an error 00180 // condition. 00181 any_violations = true; 00182 } 00183 max_num_frames = max(max_num_frames, num_frames); 00184 } 00185 00186 if (any_violations) { 00187 // Now go back through and force all components to the appropriate 00188 // length. 00189 for (ci = _components.begin(); ci != _components.end(); ++ci) { 00190 EggComponentData *component = (*ci); 00191 int num_frames = component->get_num_frames(model_index); 00192 if (num_frames > 1 && max_num_frames != num_frames) { 00193 component->extend_to(model_index, max_num_frames); 00194 } 00195 } 00196 } 00197 00198 return !any_violations; 00199 } 00200 00201 //////////////////////////////////////////////////////////////////// 00202 // Function: EggCharacterData::do_reparent 00203 // Access: Public 00204 // Description: Begins the process of restructuring the joint 00205 // hierarchy according to the previous calls to 00206 // reparent_to() on various joints. This will reparent 00207 // the joint hierachy in all models as requested, while 00208 // adjusting the transforms as appropriate so that each 00209 // joint retains the same net transform across all 00210 // frames that it had before the operation. Returns 00211 // true on success, false on failure. 00212 //////////////////////////////////////////////////////////////////// 00213 bool EggCharacterData:: 00214 do_reparent() { 00215 typedef pset<EggJointData *> InvalidSet; 00216 InvalidSet invalid_set; 00217 00218 // To begin, make sure the list of new_children is accurate. 00219 Joints::const_iterator ji; 00220 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00221 EggJointData *joint_data = (*ji); 00222 joint_data->do_begin_reparent(); 00223 } 00224 // We also need to clear the children on the root joint, but the 00225 // root joint doesn't get any of the other operations (including 00226 // finish_reparent) applied to it. 00227 _root_joint->do_begin_reparent(); 00228 00229 00230 // Now, check for cycles in the new parenting hierarchy, and also 00231 // sort the joints in order from top to bottom in the new hierarchy. 00232 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00233 EggJointData *joint_data = (*ji); 00234 pset<EggJointData *> chain; 00235 if (joint_data->calc_new_parent_depth(chain)) { 00236 nout << "Cycle detected in parent chain for " << joint_data->get_name() 00237 << "!\n"; 00238 return false; 00239 } 00240 } 00241 sort(_joints.begin(), _joints.end(), OrderJointsByNewDepth()); 00242 00243 // Now compute the new transforms for the joints' new positions. 00244 // This is done recursively through the new parent hierarchy, so we 00245 // can take advantage of caching the net value for a particular 00246 // frame. 00247 Models::const_iterator mi; 00248 for (mi = _models.begin(); mi != _models.end(); ++mi) { 00249 EggCharacterDb db; 00250 int model_index = (*mi)._model_index; 00251 int num_frames = get_num_frames(model_index); 00252 nout << " computing " << (mi - _models.begin()) + 1 00253 << " of " << _models.size() 00254 << ": " << (*mi)._egg_data->get_egg_filename() 00255 << " (" << num_frames << " frames)\n"; 00256 for (int f = 0; f < num_frames; f++) { 00257 // First, walk through all the joints and flush the computed net 00258 // transforms from before. 00259 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00260 EggJointData *joint_data = (*ji); 00261 joint_data->do_begin_compute_reparent(); 00262 } 00263 _root_joint->do_begin_compute_reparent(); 00264 00265 // Now go back through and compute the reparented transforms, 00266 // caching net transforms as necessary. 00267 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00268 EggJointData *joint_data = (*ji); 00269 if (!joint_data->do_compute_reparent(model_index, f, db)) { 00270 // Oops, we got an invalid transform. 00271 invalid_set.insert(joint_data); 00272 } 00273 } 00274 } 00275 00276 // Finally, apply the computations to the joints. 00277 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00278 EggJointData *joint_data = (*ji); 00279 if (!joint_data->do_joint_rebuild(model_index, db)) { 00280 invalid_set.insert(joint_data); 00281 } 00282 } 00283 } 00284 00285 // Now remove all of the old children and add in the new children. 00286 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00287 EggJointData *joint_data = (*ji); 00288 joint_data->do_finish_reparent(); 00289 } 00290 00291 // Report the set of joints that failed. It really shouldn't be 00292 // possible for any joints to fail, so if you see anything reported 00293 // here, something went wrong at a fundamental level. Perhaps a 00294 // problem with decompose_matrix(). 00295 InvalidSet::const_iterator si; 00296 for (si = invalid_set.begin(); si != invalid_set.end(); ++si) { 00297 EggJointData *joint_data = (*si); 00298 // Don't bother reporting joints that no longer have a parent, 00299 // since we don't care about joints that are now outside the 00300 // hierarchy. 00301 if (joint_data->get_parent() != (EggJointData *)NULL) { 00302 nout << "Warning: reparenting " << joint_data->get_name() 00303 << " to "; 00304 if (joint_data->get_parent() == _root_joint) { 00305 nout << "the root"; 00306 } else { 00307 nout << joint_data->get_parent()->get_name(); 00308 } 00309 nout << " results in an invalid transform.\n"; 00310 } 00311 } 00312 00313 return invalid_set.empty(); 00314 } 00315 00316 //////////////////////////////////////////////////////////////////// 00317 // Function: EggCharacterData::choose_optimal_hierarchy 00318 // Access: Public 00319 // Description: Chooses the best possible parent joint for each of 00320 // the joints in the hierarchy, based on the score 00321 // computed by EggJointData::score_reparent_to(). This 00322 // is a fairly expensive operation that involves lots of 00323 // recomputing of transforms across the hierarchy. 00324 // 00325 // The joints are not actually reparented yet, but the 00326 // new_parent of each joint is set. Call do_reparent() 00327 // to actually perform the suggested reparenting 00328 // operation. 00329 //////////////////////////////////////////////////////////////////// 00330 void EggCharacterData:: 00331 choose_optimal_hierarchy() { 00332 EggCharacterDb db; 00333 00334 Joints::const_iterator ji, jj; 00335 for (ji = _joints.begin(); ji != _joints.end(); ++ji) { 00336 EggJointData *joint_data = (*ji); 00337 00338 EggJointData *best_parent = joint_data->get_parent(); 00339 int best_score = joint_data->score_reparent_to(best_parent, db); 00340 00341 for (jj = _joints.begin(); jj != _joints.end(); ++jj) { 00342 EggJointData *possible_parent = (*jj); 00343 if (possible_parent != joint_data && possible_parent != best_parent && 00344 !joint_data->is_new_ancestor(possible_parent)) { 00345 00346 int score = joint_data->score_reparent_to(possible_parent, db); 00347 if (score >= 0 && (best_score < 0 || score < best_score)) { 00348 best_parent = possible_parent; 00349 best_score = score; 00350 } 00351 } 00352 } 00353 00354 // Also consider reparenting the node to the root. 00355 EggJointData *possible_parent = get_root_joint(); 00356 if (possible_parent != best_parent) { 00357 int score = joint_data->score_reparent_to(possible_parent, db); 00358 if (score >= 0 && (best_score < 0 || score < best_score)) { 00359 best_parent = possible_parent; 00360 best_score = score; 00361 } 00362 } 00363 00364 if (best_parent != (EggJointData *)NULL && 00365 best_parent != joint_data->_parent) { 00366 nout << "best parent for " << joint_data->get_name() << " is " 00367 << best_parent->get_name() << "\n"; 00368 joint_data->reparent_to(best_parent); 00369 } 00370 } 00371 } 00372 00373 //////////////////////////////////////////////////////////////////// 00374 // Function: EggCharacterData::find_slider 00375 // Access: Public 00376 // Description: Returns the slider with the indicated name, or NULL 00377 // if no slider has that name. 00378 //////////////////////////////////////////////////////////////////// 00379 EggSliderData *EggCharacterData:: 00380 find_slider(const string &name) const { 00381 SlidersByName::const_iterator si; 00382 si = _sliders_by_name.find(name); 00383 if (si != _sliders_by_name.end()) { 00384 return (*si).second; 00385 } 00386 00387 return NULL; 00388 } 00389 00390 //////////////////////////////////////////////////////////////////// 00391 // Function: EggCharacterData::make_slider 00392 // Access: Public 00393 // Description: Returns the slider matching the indicated name. If 00394 // no such slider exists already, creates a new one. 00395 //////////////////////////////////////////////////////////////////// 00396 EggSliderData *EggCharacterData:: 00397 make_slider(const string &name) { 00398 SlidersByName::const_iterator si; 00399 si = _sliders_by_name.find(name); 00400 if (si != _sliders_by_name.end()) { 00401 return (*si).second; 00402 } 00403 00404 EggSliderData *slider = _collection->make_slider_data(this); 00405 slider->set_name(name); 00406 _sliders_by_name.insert(SlidersByName::value_type(name, slider)); 00407 _sliders.push_back(slider); 00408 _components.push_back(slider); 00409 return slider; 00410 } 00411 00412 //////////////////////////////////////////////////////////////////// 00413 // Function: EggCharacterData::estimate_db_size 00414 // Access: Public 00415 // Description: Returns the estimated amount of memory, in megabytes, 00416 // that will be required to perform the do_reparent() 00417 // operation. This is used mainly be EggCharacterDb to 00418 // decide up front whether to store this data in-RAM or 00419 // on-disk. 00420 //////////////////////////////////////////////////////////////////// 00421 size_t EggCharacterData:: 00422 estimate_db_size() const { 00423 // Count how much memory we will need to store the interim 00424 // transforms. This is models * joints * frames * 3 * 00425 // sizeof(LMatrix4d). 00426 size_t mj_frames = 0; 00427 Models::const_iterator mi; 00428 for (mi = _models.begin(); mi != _models.end(); ++mi) { 00429 int model_index = (*mi)._model_index; 00430 size_t num_frames = (size_t)get_num_frames(model_index); 00431 mj_frames += num_frames * _joints.size(); 00432 } 00433 00434 // We do this operation a bit carefully, to guard against integer 00435 // overflow. 00436 size_t mb_needed = ((mj_frames * 3 / 1024) * sizeof(LMatrix4d)) / 1024; 00437 00438 return mb_needed; 00439 } 00440 00441 00442 //////////////////////////////////////////////////////////////////// 00443 // Function: EggCharacterData::write 00444 // Access: Public, Virtual 00445 // Description: 00446 //////////////////////////////////////////////////////////////////// 00447 void EggCharacterData:: 00448 write(ostream &out, int indent_level) const { 00449 indent(out, indent_level) 00450 << "Character " << get_name() << ":\n"; 00451 get_root_joint()->write(out, indent_level + 2); 00452 00453 Sliders::const_iterator si; 00454 for (si = _sliders.begin(); si != _sliders.end(); ++si) { 00455 EggSliderData *slider = (*si); 00456 slider->write(out, indent_level + 2); 00457 } 00458 }