00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "computedVerticesMaker.h"
00020 #include "characterMaker.h"
00021
00022 #include "characterJoint.h"
00023 #include "character.h"
00024 #include "computedVertices.h"
00025 #include "eggNode.h"
00026 #include "eggGroup.h"
00027 #include "eggVertex.h"
00028
00029 #include <algorithm>
00030
00031
00032
00033
00034
00035
00036 ComputedVerticesMaker::
00037 ComputedVerticesMaker() {
00038 _coords= PTA_Vertexf::empty_array(0);
00039 _norms= PTA_Normalf::empty_array(0);
00040 _colors= PTA_Colorf::empty_array(0);
00041 _texcoords= PTA_TexCoordf::empty_array(0);
00042 _current_vc = NULL;
00043 }
00044
00045
00046
00047
00048
00049
00050
00051 void ComputedVerticesMaker::
00052 begin_new_space() {
00053 _current_jw.clear();
00054 _current_vc = NULL;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063 void ComputedVerticesMaker::
00064 add_joint(EggNode *joint, double membership) {
00065
00066
00067 assert(_current_vc == NULL);
00068
00069 if (membership == 0.0) {
00070 return;
00071 }
00072
00073 assert(membership > 0.0);
00074
00075 JointWeights::iterator jwi = _current_jw.find(joint);
00076
00077 if (jwi != _current_jw.end()) {
00078
00079
00080 (*jwi).second += membership;
00081 } else {
00082
00083 _current_jw[joint] = membership;
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 void ComputedVerticesMaker::
00095 add_vertex_joints(EggVertex *vertex, EggNode *object) {
00096 if (vertex->gref_size() == 0) {
00097
00098
00099 EggGroupNode *egg_joint = object->get_parent();
00100
00101
00102
00103
00104
00105
00106 EggGroup *egg_group = (EggGroup *)NULL;
00107 if (egg_joint->is_of_type(EggGroup::get_class_type())) {
00108 egg_group = DCAST(EggGroup, egg_joint);
00109 }
00110 while (egg_group != (EggGroup *)NULL &&
00111 egg_group->get_group_type() != EggGroup::GT_joint &&
00112 egg_group->get_dart_type() == EggGroup::DT_none) {
00113 nassertv(egg_group->get_parent() != (EggGroupNode *)NULL);
00114 egg_joint = egg_group->get_parent();
00115 egg_group = (EggGroup *)NULL;
00116 if (egg_joint->is_of_type(EggGroup::get_class_type())) {
00117 egg_group = DCAST(EggGroup, egg_joint);
00118 }
00119 }
00120
00121 add_joint(egg_joint, 1.0);
00122
00123 } else {
00124
00125 EggVertex::GroupRef::const_iterator gri;
00126 for (gri = vertex->gref_begin(); gri != vertex->gref_end(); ++gri) {
00127 EggGroup *egg_joint = (*gri);
00128 double membership = egg_joint->get_vertex_membership(vertex);
00129 add_joint(egg_joint, membership);
00130 }
00131 }
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 void ComputedVerticesMaker::
00145 mark_space() {
00146
00147 assert(_current_vc == NULL);
00148
00149 _current_jw.normalize_weights();
00150
00151
00152
00153
00154 _current_vc = &_transforms[_current_jw];
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 int ComputedVerticesMaker::
00166 add_vertex(const Vertexd &vertex, const EggMorphVertexList &morphs,
00167 const LMatrix4d &transform) {
00168
00169
00170 assert(_current_vc != NULL);
00171
00172 Vertexf tv = LCAST(float, vertex * transform);
00173 int index = _current_vc->_vmap.add_value(tv, morphs, _coords);
00174 _current_vc->_vindex.insert(index);
00175
00176
00177 EggMorphVertexList::const_iterator mli;
00178 for (mli = morphs.begin(); mli != morphs.end(); ++mli) {
00179 const EggMorphVertex &morph = (*mli);
00180 LVector3d offset = morph.get_offset() * transform;
00181 if (!offset.almost_equal(LVector3d(0.0, 0.0, 0.0), 0.0001)) {
00182 MorphList &mlist = _morphs[morph.get_name()];
00183
00184
00185 VertexMorphList::iterator vmi = mlist._vmorphs.find(index);
00186 if (vmi != mlist._vmorphs.end()) {
00187
00188 assert(offset.almost_equal(LCAST(double, (*vmi).second), 0.0001));
00189 } else {
00190
00191 mlist._vmorphs[index] = LCAST(float, offset);
00192 }
00193 }
00194 }
00195
00196 return index;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 int ComputedVerticesMaker::
00207 add_normal(const Normald &normal, const EggMorphNormalList &morphs,
00208 const LMatrix4d &transform) {
00209
00210
00211 assert(_current_vc != NULL);
00212
00213 Normald norm = normal * transform;
00214 norm.normalize();
00215 int index = _current_vc->_nmap.add_value(LCAST(float, norm), morphs, _norms);
00216 _current_vc->_nindex.insert(index);
00217
00218
00219 EggMorphNormalList::const_iterator mli;
00220 for (mli = morphs.begin(); mli != morphs.end(); ++mli) {
00221 const EggMorphNormal &morph = (*mli);
00222 LVector3d offset = morph.get_offset() * transform;
00223 if (!offset.almost_equal(LVector3d(0.0, 0.0, 0.0), 0.0001)) {
00224 MorphList &mlist = _morphs[morph.get_name()];
00225
00226
00227 NormalMorphList::iterator vmi = mlist._nmorphs.find(index);
00228 if (vmi != mlist._nmorphs.end()) {
00229
00230 assert(offset.almost_equal(LCAST(double, (*vmi).second), 0.0001));
00231 } else {
00232
00233 mlist._nmorphs[index] = LCAST(float, offset);
00234 }
00235 }
00236 }
00237
00238 return index;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 int ComputedVerticesMaker::
00250 add_texcoord(const TexCoordd &texcoord, const EggMorphTexCoordList &morphs,
00251 const LMatrix3d &transform) {
00252 TexCoordf ttc = LCAST(float, texcoord * transform);
00253 int index = _tmap.add_value(ttc, morphs, _texcoords);
00254 _tindex.insert(index);
00255
00256
00257 EggMorphTexCoordList::const_iterator mli;
00258 for (mli = morphs.begin(); mli != morphs.end(); ++mli) {
00259 const EggMorphTexCoord &morph = (*mli);
00260 LVector2d offset = morph.get_offset() * transform;
00261 if (!offset.almost_equal(LVector2d(0.0, 0.0), 0.0001)) {
00262 MorphList &mlist = _morphs[morph.get_name()];
00263
00264
00265 TexCoordMorphList::iterator vmi = mlist._tmorphs.find(index);
00266 if (vmi != mlist._tmorphs.end()) {
00267
00268 assert(offset.almost_equal(LCAST(double, (*vmi).second), 0.0001));
00269 } else {
00270
00271 mlist._tmorphs[index] = LCAST(float, offset);
00272 }
00273 }
00274 }
00275
00276 return index;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286 int ComputedVerticesMaker::
00287 add_color(const Colorf &color, const EggMorphColorList &morphs) {
00288 int index = _cmap.add_value(color, morphs, _colors);
00289 _cindex.insert(index);
00290
00291
00292 EggMorphColorList::const_iterator mli;
00293 for (mli = morphs.begin(); mli != morphs.end(); ++mli) {
00294 const EggMorphColor &morph = (*mli);
00295 LVector4f offset = morph.get_offset();
00296 if (!offset.almost_equal(LVector4f(0.0, 0.0, 0.0, 0.0), 0.0001)) {
00297 MorphList &mlist = _morphs[morph.get_name()];
00298
00299
00300 ColorMorphList::iterator vmi = mlist._cmorphs.find(index);
00301 if (vmi != mlist._cmorphs.end()) {
00302
00303 assert(offset.almost_equal((*vmi).second, 0.0001));
00304 } else {
00305
00306 mlist._cmorphs[index] = offset;
00307 }
00308 }
00309 }
00310
00311 return index;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321 ComputedVertices *ComputedVerticesMaker::
00322 make_computed_vertices(Character *character, CharacterMaker &char_maker) {
00323
00324
00325 typedef pset<ComputedVertices::VertexTransform> VertexTransforms;
00326 VertexTransforms transforms;
00327
00328 TransformSpaces::const_iterator tsi;
00329 for (tsi = _transforms.begin();
00330 tsi != _transforms.end();
00331 ++tsi) {
00332 const JointWeights &jw = (*tsi).first;
00333 const VertexCollection &vc = (*tsi).second;
00334
00335 JointWeights::const_iterator jwi;
00336 for (jwi = jw.begin(); jwi != jw.end(); ++jwi) {
00337 double weight = (*jwi).second;
00338 EggNode *egg_joint = (*jwi).first;
00339 int joint_index = char_maker.egg_to_index(egg_joint);
00340
00341
00342 ComputedVertices::VertexTransform new_vt;
00343 new_vt._joint_index = joint_index;
00344 new_vt._effect = (float)weight;
00345
00346
00347
00348
00349
00350 VertexTransforms::iterator vti = transforms.insert(new_vt).first;
00351
00352
00353
00354
00355 ComputedVertices::VertexTransform &insert_vt =
00356 (ComputedVertices::VertexTransform &)*vti;
00357
00358
00359 copy(vc._vindex.begin(), vc._vindex.end(),
00360 back_inserter(insert_vt._vindex));
00361 copy(vc._nindex.begin(), vc._nindex.end(),
00362 back_inserter(insert_vt._nindex));
00363 }
00364 }
00365
00366
00367
00368 ComputedVertices *comp_verts = new ComputedVertices;
00369 copy(transforms.begin(), transforms.end(),
00370 back_inserter(comp_verts->_transforms));
00371
00372 character->_cv._coords = _coords;
00373 character->_cv._norms = _norms;
00374 character->_cv._colors = _colors;
00375 character->_cv._texcoords = _texcoords;
00376
00377
00378 Morphs::const_iterator mi;
00379 for (mi = _morphs.begin(); mi != _morphs.end(); ++mi) {
00380 const string &name = (*mi).first;
00381 const MorphList &mlist = (*mi).second;
00382
00383 int slider_index = char_maker.create_slider(name);
00384
00385 if (!mlist._vmorphs.empty()) {
00386
00387
00388
00389 comp_verts->_vertex_morphs.push_back(ComputedVerticesMorphVertex());
00390 ComputedVerticesMorphVertex &mv = comp_verts->_vertex_morphs.back();
00391 mv._slider_index = slider_index;
00392
00393 VertexMorphList::const_iterator vmi;
00394 for (vmi = mlist._vmorphs.begin();
00395 vmi != mlist._vmorphs.end();
00396 ++vmi) {
00397 mv._morphs.push_back(ComputedVerticesMorphValue3((*vmi).first,
00398 (*vmi).second));
00399 }
00400 }
00401
00402 if (!mlist._nmorphs.empty()) {
00403 comp_verts->_normal_morphs.push_back(ComputedVerticesMorphNormal());
00404 ComputedVerticesMorphNormal &mv = comp_verts->_normal_morphs.back();
00405 mv._slider_index = slider_index;
00406
00407 NormalMorphList::const_iterator vmi;
00408 for (vmi = mlist._nmorphs.begin();
00409 vmi != mlist._nmorphs.end();
00410 ++vmi) {
00411 mv._morphs.push_back(ComputedVerticesMorphValue3((*vmi).first,
00412 (*vmi).second));
00413 }
00414 }
00415
00416 if (!mlist._tmorphs.empty()) {
00417 comp_verts->_texcoord_morphs.push_back(ComputedVerticesMorphTexCoord());
00418 ComputedVerticesMorphTexCoord &mv = comp_verts->_texcoord_morphs.back();
00419 mv._slider_index = slider_index;
00420
00421 TexCoordMorphList::const_iterator vmi;
00422 for (vmi = mlist._tmorphs.begin();
00423 vmi != mlist._tmorphs.end();
00424 ++vmi) {
00425 mv._morphs.push_back(ComputedVerticesMorphValue2((*vmi).first,
00426 (*vmi).second));
00427 }
00428 }
00429
00430 if (!mlist._cmorphs.empty()) {
00431 comp_verts->_color_morphs.push_back(ComputedVerticesMorphColor());
00432 ComputedVerticesMorphColor &mv = comp_verts->_color_morphs.back();
00433 mv._slider_index = slider_index;
00434
00435 ColorMorphList::const_iterator vmi;
00436 for (vmi = mlist._cmorphs.begin();
00437 vmi != mlist._cmorphs.end();
00438 ++vmi) {
00439 mv._morphs.push_back(ComputedVerticesMorphValue4((*vmi).first,
00440 (*vmi).second));
00441 }
00442 }
00443 }
00444
00445 comp_verts->make_orig(character);
00446 return comp_verts;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455 void ComputedVerticesMaker::
00456 write(ostream &out) const {
00457 out << "ComputedVerticesMaker, "
00458 << _transforms.size() << " transform spaces, "
00459 << _coords.size() << " vertices, "
00460 << _norms.size() << " normals, "
00461 << _texcoords.size() << " uvs, "
00462 << _colors.size() << " colors.\n";
00463 TransformSpaces::const_iterator tsi;
00464 for (tsi = _transforms.begin(); tsi != _transforms.end(); ++tsi) {
00465 const JointWeights &jw = (*tsi).first;
00466 const VertexCollection &vc = (*tsi).second;
00467 out << " " << jw << " has "
00468 << vc._vindex.size() << " vertices and "
00469 << vc._nindex.size() << " normals\n";
00470 }
00471
00472 Morphs::const_iterator mi;
00473 for (mi = _morphs.begin(); mi != _morphs.end(); ++mi) {
00474 const string &name = (*mi).first;
00475 const MorphList &mlist = (*mi).second;
00476 out << name << " morphs "
00477 << mlist._vmorphs.size() << " vertices, "
00478 << mlist._nmorphs.size() << " normals, "
00479 << mlist._tmorphs.size() << " uvs, and "
00480 << mlist._cmorphs.size() << " colors.\n";
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489
00490 bool ComputedVerticesMaker::JointWeights::
00491 operator < (const JointWeights &other) const {
00492 const_iterator i = begin();
00493 const_iterator j = other.begin();
00494
00495 while (i != end() && j != other.end()) {
00496 if ((*i).first != (*j).first) {
00497 return (*i).first < (*j).first;
00498 }
00499 if ((*i).second != (*j).second) {
00500 return (*i).second < (*j).second;
00501 }
00502 ++i;
00503 ++j;
00504 }
00505
00506 if (i == end() && j != other.end()) {
00507
00508 return true;
00509 }
00510
00511 if (i != end() && j == other.end()) {
00512
00513 return false;
00514 }
00515
00516
00517 return false;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526 void ComputedVerticesMaker::JointWeights::
00527 normalize_weights() {
00528 if (!empty()) {
00529 double net_weight = 0.0;
00530
00531 iterator i;
00532 for (i = begin(); i != end(); ++i) {
00533 double weight = (*i).second;
00534 assert(weight > 0.0);
00535 net_weight += weight;
00536 }
00537 assert(net_weight != 0.0);
00538
00539 for (i = begin(); i != end(); ++i) {
00540 (*i).second /= net_weight;
00541 }
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 void ComputedVerticesMaker::JointWeights::
00552 output(ostream &out) const {
00553 out << "jw(";
00554 if (!empty()) {
00555 const_iterator i = begin();
00556 out << (*i).first->get_name() << ":" << (*i).second;
00557 for (++i; i != end(); ++i) {
00558 out << " " << (*i).first->get_name() << ":" << (*i).second;
00559 }
00560 }
00561 out << ")";
00562 }