2
0

eggCharacterData.cxx 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file eggCharacterData.cxx
  10. * @author drose
  11. * @date 2001-02-23
  12. */
  13. #include "eggCharacterData.h"
  14. #include "eggCharacterCollection.h"
  15. #include "eggCharacterDb.h"
  16. #include "eggJointData.h"
  17. #include "eggSliderData.h"
  18. #include "indent.h"
  19. #include <algorithm>
  20. // An STL function object to sort the joint list in order from highest to
  21. // lowest in the new hierarchy. Used in do_reparent().
  22. class OrderJointsByNewDepth {
  23. public:
  24. bool operator()(const EggJointData *a, const EggJointData *b) const {
  25. return a->_new_parent_depth < b->_new_parent_depth;
  26. }
  27. };
  28. /**
  29. *
  30. */
  31. EggCharacterData::
  32. EggCharacterData(EggCharacterCollection *collection) :
  33. _component_names("_", "joint_")
  34. {
  35. _collection = collection;
  36. _root_joint = _collection->make_joint_data(this);
  37. // The fictitious root joint is not added to the _components list.
  38. }
  39. /**
  40. *
  41. */
  42. EggCharacterData::
  43. ~EggCharacterData() {
  44. delete _root_joint;
  45. Sliders::iterator si;
  46. for (si = _sliders.begin(); si != _sliders.end(); ++si) {
  47. EggSliderData *slider = (*si);
  48. delete slider;
  49. }
  50. }
  51. /**
  52. * Renames all of the models in the character data to the indicated name.
  53. * This is the name that is used to identify unique skeleton hierarchies; if
  54. * you set two different models to the same name, they will be loaded together
  55. * as if they are expected to have the same skeleton hierarchy.
  56. */
  57. void EggCharacterData::
  58. rename_char(const std::string &name) {
  59. Models::iterator mi;
  60. for (mi = _models.begin(); mi != _models.end(); ++mi) {
  61. (*mi)._model_root->set_name(name);
  62. }
  63. set_name(name);
  64. }
  65. /**
  66. * Indicates that the given model_index (with the indicated model_root) is
  67. * associated with this character. This is normally called by the
  68. * EggCharacterCollection class as new models are discovered.
  69. *
  70. * A "model" here is either a character model (or one LOD of a character
  71. * model), or a character animation file: in either case, a hierarchy of
  72. * joints.
  73. */
  74. void EggCharacterData::
  75. add_model(int model_index, EggNode *model_root, EggData *egg_data) {
  76. Model m;
  77. m._model_index = model_index;
  78. m._model_root = model_root;
  79. m._egg_data = egg_data;
  80. _models.push_back(m);
  81. }
  82. /**
  83. * Returns the number of frames of animation of the indicated model. This is
  84. * more reliable than asking a particular joint or slider of the animation for
  85. * its number of frames, since a particular joint may have only 1 frame (if it
  86. * is unanimated), even though the overall animation has many frames.
  87. */
  88. int EggCharacterData::
  89. get_num_frames(int model_index) const {
  90. int max_num_frames = 0;
  91. Components::const_iterator ci;
  92. for (ci = _components.begin(); ci != _components.end(); ++ci) {
  93. EggComponentData *component = (*ci);
  94. int num_frames = component->get_num_frames(model_index);
  95. if (num_frames > 1) {
  96. // We have a winner. Assume all other components will be similar.
  97. return num_frames;
  98. }
  99. max_num_frames = std::max(max_num_frames, num_frames);
  100. }
  101. // Every component had either 1 frame or 0 frames. Return the maximum of
  102. // these.
  103. return max_num_frames;
  104. }
  105. /**
  106. * Returns the stated frame rate of the specified model. Similar to
  107. * get_num_frames().
  108. */
  109. double EggCharacterData::
  110. get_frame_rate(int model_index) const {
  111. Components::const_iterator ci;
  112. for (ci = _components.begin(); ci != _components.end(); ++ci) {
  113. EggComponentData *component = (*ci);
  114. double frame_rate = component->get_frame_rate(model_index);
  115. if (frame_rate != 0.0) {
  116. // We have a winner. Assume all other components will be similar.
  117. return frame_rate;
  118. }
  119. }
  120. return 0.0;
  121. }
  122. /**
  123. * Walks through each component and ensures that all have the same number of
  124. * frames of animation (except for those that contain 0 or 1 frames, of
  125. * course). Returns true if all are valid, false if there is a discreprency
  126. * (in which case the shorter component are extended).
  127. */
  128. bool EggCharacterData::
  129. check_num_frames(int model_index) {
  130. int max_num_frames = 0;
  131. bool any_violations = false;
  132. Components::const_iterator ci;
  133. for (ci = _components.begin(); ci != _components.end(); ++ci) {
  134. EggComponentData *component = (*ci);
  135. int num_frames = component->get_num_frames(model_index);
  136. if (num_frames > 1 && max_num_frames > 1 &&
  137. max_num_frames != num_frames) {
  138. // If we have two different opinions about the number of frames (other
  139. // than 0 or 1), we have a discrepency. This is an error condition.
  140. any_violations = true;
  141. }
  142. max_num_frames = std::max(max_num_frames, num_frames);
  143. }
  144. if (any_violations) {
  145. // Now go back through and force all components to the appropriate length.
  146. for (ci = _components.begin(); ci != _components.end(); ++ci) {
  147. EggComponentData *component = (*ci);
  148. int num_frames = component->get_num_frames(model_index);
  149. if (num_frames > 1 && max_num_frames != num_frames) {
  150. component->extend_to(model_index, max_num_frames);
  151. }
  152. }
  153. }
  154. return !any_violations;
  155. }
  156. /**
  157. * Begins the process of restructuring the joint hierarchy according to the
  158. * previous calls to reparent_to() on various joints. This will reparent the
  159. * joint hierachy in all models as requested, while adjusting the transforms
  160. * as appropriate so that each joint retains the same net transform across all
  161. * frames that it had before the operation. Returns true on success, false on
  162. * failure.
  163. */
  164. bool EggCharacterData::
  165. do_reparent() {
  166. typedef pset<EggJointData *> InvalidSet;
  167. InvalidSet invalid_set;
  168. // To begin, make sure the list of new_children is accurate.
  169. Joints::const_iterator ji;
  170. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  171. EggJointData *joint_data = (*ji);
  172. joint_data->do_begin_reparent();
  173. }
  174. // We also need to clear the children on the root joint, but the root joint
  175. // doesn't get any of the other operations (including finish_reparent)
  176. // applied to it.
  177. _root_joint->do_begin_reparent();
  178. // Now, check for cycles in the new parenting hierarchy, and also sort the
  179. // joints in order from top to bottom in the new hierarchy.
  180. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  181. EggJointData *joint_data = (*ji);
  182. pset<EggJointData *> chain;
  183. if (joint_data->calc_new_parent_depth(chain)) {
  184. nout << "Cycle detected in parent chain for " << joint_data->get_name()
  185. << "!\n";
  186. return false;
  187. }
  188. }
  189. sort(_joints.begin(), _joints.end(), OrderJointsByNewDepth());
  190. // Now compute the new transforms for the joints' new positions. This is
  191. // done recursively through the new parent hierarchy, so we can take
  192. // advantage of caching the net value for a particular frame.
  193. Models::const_iterator mi;
  194. for (mi = _models.begin(); mi != _models.end(); ++mi) {
  195. EggCharacterDb db;
  196. int model_index = (*mi)._model_index;
  197. int num_frames = get_num_frames(model_index);
  198. nout << " computing " << (mi - _models.begin()) + 1
  199. << " of " << _models.size()
  200. << ": " << (*mi)._egg_data->get_egg_filename()
  201. << " (" << num_frames << " frames)\n";
  202. for (int f = 0; f < num_frames; f++) {
  203. // First, walk through all the joints and flush the computed net
  204. // transforms from before.
  205. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  206. EggJointData *joint_data = (*ji);
  207. joint_data->do_begin_compute_reparent();
  208. }
  209. _root_joint->do_begin_compute_reparent();
  210. // Now go back through and compute the reparented transforms, caching
  211. // net transforms as necessary.
  212. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  213. EggJointData *joint_data = (*ji);
  214. if (!joint_data->do_compute_reparent(model_index, f, db)) {
  215. // Oops, we got an invalid transform.
  216. invalid_set.insert(joint_data);
  217. }
  218. }
  219. }
  220. // Finally, apply the computations to the joints.
  221. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  222. EggJointData *joint_data = (*ji);
  223. if (!joint_data->do_joint_rebuild(model_index, db)) {
  224. invalid_set.insert(joint_data);
  225. }
  226. }
  227. }
  228. // Now remove all of the old children and add in the new children.
  229. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  230. EggJointData *joint_data = (*ji);
  231. joint_data->do_finish_reparent();
  232. }
  233. // Report the set of joints that failed. It really shouldn't be possible
  234. // for any joints to fail, so if you see anything reported here, something
  235. // went wrong at a fundamental level. Perhaps a problem with
  236. // decompose_matrix().
  237. InvalidSet::const_iterator si;
  238. for (si = invalid_set.begin(); si != invalid_set.end(); ++si) {
  239. EggJointData *joint_data = (*si);
  240. // Don't bother reporting joints that no longer have a parent, since we
  241. // don't care about joints that are now outside the hierarchy.
  242. if (joint_data->get_parent() != nullptr) {
  243. nout << "Warning: reparenting " << joint_data->get_name()
  244. << " to ";
  245. if (joint_data->get_parent() == _root_joint) {
  246. nout << "the root";
  247. } else {
  248. nout << joint_data->get_parent()->get_name();
  249. }
  250. nout << " results in an invalid transform.\n";
  251. }
  252. }
  253. return invalid_set.empty();
  254. }
  255. /**
  256. * Chooses the best possible parent joint for each of the joints in the
  257. * hierarchy, based on the score computed by
  258. * EggJointData::score_reparent_to(). This is a fairly expensive operation
  259. * that involves lots of recomputing of transforms across the hierarchy.
  260. *
  261. * The joints are not actually reparented yet, but the new_parent of each
  262. * joint is set. Call do_reparent() to actually perform the suggested
  263. * reparenting operation.
  264. */
  265. void EggCharacterData::
  266. choose_optimal_hierarchy() {
  267. EggCharacterDb db;
  268. Joints::const_iterator ji, jj;
  269. for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
  270. EggJointData *joint_data = (*ji);
  271. EggJointData *best_parent = joint_data->get_parent();
  272. int best_score = joint_data->score_reparent_to(best_parent, db);
  273. for (jj = _joints.begin(); jj != _joints.end(); ++jj) {
  274. EggJointData *possible_parent = (*jj);
  275. if (possible_parent != joint_data && possible_parent != best_parent &&
  276. !joint_data->is_new_ancestor(possible_parent)) {
  277. int score = joint_data->score_reparent_to(possible_parent, db);
  278. if (score >= 0 && (best_score < 0 || score < best_score)) {
  279. best_parent = possible_parent;
  280. best_score = score;
  281. }
  282. }
  283. }
  284. // Also consider reparenting the node to the root.
  285. EggJointData *possible_parent = get_root_joint();
  286. if (possible_parent != best_parent) {
  287. int score = joint_data->score_reparent_to(possible_parent, db);
  288. if (score >= 0 && (best_score < 0 || score < best_score)) {
  289. best_parent = possible_parent;
  290. best_score = score;
  291. }
  292. }
  293. if (best_parent != nullptr &&
  294. best_parent != joint_data->_parent) {
  295. nout << "best parent for " << joint_data->get_name() << " is "
  296. << best_parent->get_name() << "\n";
  297. joint_data->reparent_to(best_parent);
  298. }
  299. }
  300. }
  301. /**
  302. * Returns the slider with the indicated name, or NULL if no slider has that
  303. * name.
  304. */
  305. EggSliderData *EggCharacterData::
  306. find_slider(const std::string &name) const {
  307. SlidersByName::const_iterator si;
  308. si = _sliders_by_name.find(name);
  309. if (si != _sliders_by_name.end()) {
  310. return (*si).second;
  311. }
  312. return nullptr;
  313. }
  314. /**
  315. * Returns the slider matching the indicated name. If no such slider exists
  316. * already, creates a new one.
  317. */
  318. EggSliderData *EggCharacterData::
  319. make_slider(const std::string &name) {
  320. SlidersByName::const_iterator si;
  321. si = _sliders_by_name.find(name);
  322. if (si != _sliders_by_name.end()) {
  323. return (*si).second;
  324. }
  325. EggSliderData *slider = _collection->make_slider_data(this);
  326. slider->set_name(name);
  327. _sliders_by_name.insert(SlidersByName::value_type(name, slider));
  328. _sliders.push_back(slider);
  329. _components.push_back(slider);
  330. return slider;
  331. }
  332. /**
  333. * Returns the estimated amount of memory, in megabytes, that will be required
  334. * to perform the do_reparent() operation. This is used mainly be
  335. * EggCharacterDb to decide up front whether to store this data in-RAM or on-
  336. * disk.
  337. */
  338. size_t EggCharacterData::
  339. estimate_db_size() const {
  340. // Count how much memory we will need to store the interim transforms. This
  341. // is models * joints * frames * 3 * sizeof(LMatrix4d).
  342. size_t mj_frames = 0;
  343. Models::const_iterator mi;
  344. for (mi = _models.begin(); mi != _models.end(); ++mi) {
  345. int model_index = (*mi)._model_index;
  346. size_t num_frames = (size_t)get_num_frames(model_index);
  347. mj_frames += num_frames * _joints.size();
  348. }
  349. // We do this operation a bit carefully, to guard against integer overflow.
  350. size_t mb_needed = ((mj_frames * 3 / 1024) * sizeof(LMatrix4d)) / 1024;
  351. return mb_needed;
  352. }
  353. /**
  354. *
  355. */
  356. void EggCharacterData::
  357. write(std::ostream &out, int indent_level) const {
  358. indent(out, indent_level)
  359. << "Character " << get_name() << ":\n";
  360. get_root_joint()->write(out, indent_level + 2);
  361. Sliders::const_iterator si;
  362. for (si = _sliders.begin(); si != _sliders.end(); ++si) {
  363. EggSliderData *slider = (*si);
  364. slider->write(out, indent_level + 2);
  365. }
  366. }