00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00025
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
00036
00037
00038
00039 EggCharacterData::
00040 EggCharacterData(EggCharacterCollection *collection) :
00041 _component_names("_", "joint_")
00042 {
00043 _collection = collection;
00044 _root_joint = _collection->make_joint_data(this);
00045
00046 }
00047
00048
00049
00050
00051
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
00066
00067
00068
00069
00070
00071
00072
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
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
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
00108
00109
00110
00111
00112
00113
00114
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
00125
00126 return num_frames;
00127 }
00128 max_num_frames = max(max_num_frames, num_frames);
00129 }
00130
00131
00132
00133 return max_num_frames;
00134 }
00135
00136
00137
00138
00139
00140
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
00150
00151 return frame_rate;
00152 }
00153 }
00154
00155 return 0.0;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
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
00179
00180
00181 any_violations = true;
00182 }
00183 max_num_frames = max(max_num_frames, num_frames);
00184 }
00185
00186 if (any_violations) {
00187
00188
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
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 bool EggCharacterData::
00214 do_reparent() {
00215 typedef pset<EggJointData *> InvalidSet;
00216 InvalidSet invalid_set;
00217
00218
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
00225
00226
00227 _root_joint->do_begin_reparent();
00228
00229
00230
00231
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
00244
00245
00246
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
00258
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
00266
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
00271 invalid_set.insert(joint_data);
00272 }
00273 }
00274 }
00275
00276
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
00286 for (ji = _joints.begin(); ji != _joints.end(); ++ji) {
00287 EggJointData *joint_data = (*ji);
00288 joint_data->do_finish_reparent();
00289 }
00290
00291
00292
00293
00294
00295 InvalidSet::const_iterator si;
00296 for (si = invalid_set.begin(); si != invalid_set.end(); ++si) {
00297 EggJointData *joint_data = (*si);
00298
00299
00300
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
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
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
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
00375
00376
00377
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
00392
00393
00394
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
00414
00415
00416
00417
00418
00419
00420
00421 size_t EggCharacterData::
00422 estimate_db_size() const {
00423
00424
00425
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
00435
00436 size_t mb_needed = ((mj_frames * 3 / 1024) * sizeof(LMatrix4d)) / 1024;
00437
00438 return mb_needed;
00439 }
00440
00441
00442
00443
00444
00445
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 }