00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "characterMaker.h"
00020 #include "eggLoader.h"
00021 #include "config_egg2pg.h"
00022
00023 #include "computedVertices.h"
00024 #include "eggGroup.h"
00025 #include "eggPrimitive.h"
00026 #include "partGroup.h"
00027 #include "characterJoint.h"
00028 #include "characterJointBundle.h"
00029 #include "characterSlider.h"
00030 #include "character.h"
00031 #include "transformState.h"
00032
00033
00034
00035
00036
00037
00038 CharacterMaker::
00039 CharacterMaker(EggGroup *root, EggLoader &loader)
00040 : _loader(loader), _egg_root(root) {
00041
00042 _character_node = new Character(_egg_root->get_name());
00043 _bundle = _character_node->get_bundle();
00044
00045 _morph_root = (PartGroup *)NULL;
00046 _skeleton_root = new PartGroup(_bundle, "<skeleton>");
00047 }
00048
00049
00050
00051
00052
00053
00054 Character *CharacterMaker::
00055 make_node() {
00056 make_bundle();
00057 _character_node->_parts = _parts;
00058 return _character_node;
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 PartGroup *CharacterMaker::
00071 egg_to_part(EggNode *egg_node) const {
00072 int index = egg_to_index(egg_node);
00073 if (index < 0) {
00074
00075
00076 return _bundle;
00077 }
00078 nassertr(index < (int)_parts.size(), NULL);
00079 return _parts[index];
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 int CharacterMaker::
00089 egg_to_index(EggNode *egg_node) const {
00090 NodeMap::const_iterator nmi = _node_map.find(egg_node);
00091 if (nmi == _node_map.end()) {
00092 return -1;
00093 }
00094 return (*nmi).second;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 PandaNode *CharacterMaker::
00106 part_to_node(PartGroup *part) const {
00107 if (part->is_of_type(CharacterJoint::get_class_type())) {
00108 CharacterJoint *joint = DCAST(CharacterJoint, part);
00109 if (joint->_geom_node != (PandaNode *)NULL) {
00110 return joint->_geom_node;
00111 }
00112 }
00113
00114 return _character_node;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 int CharacterMaker::
00127 create_slider(const string &name) {
00128 if (_morph_root == (PartGroup *)NULL) {
00129 _morph_root = new PartGroup(_bundle, "morph");
00130 }
00131 CharacterSlider *slider = new CharacterSlider(_morph_root, name);
00132 int index = _parts.size();
00133 _parts.push_back(slider);
00134 return index;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 CharacterJointBundle *CharacterMaker::
00144 make_bundle() {
00145 build_joint_hierarchy(_egg_root, _skeleton_root);
00146 _bundle->sort_descendants();
00147
00148 parent_joint_nodes(_skeleton_root);
00149 make_geometry(_egg_root);
00150
00151 _character_node->_computed_vertices =
00152 _comp_verts_maker.make_computed_vertices(_character_node, *this);
00153
00154 return _bundle;
00155 }
00156
00157
00158
00159
00160
00161
00162 void CharacterMaker::
00163 build_joint_hierarchy(EggNode *egg_node, PartGroup *part) {
00164 int index = -1;
00165
00166 if (egg_node->is_of_type(EggGroup::get_class_type())) {
00167 EggGroup *egg_group = DCAST(EggGroup, egg_node);
00168
00169
00170
00171 if (egg_group->get_group_type() == EggGroup::GT_joint) {
00172
00173
00174 LMatrix4d matd;
00175 if (egg_group->has_transform()) {
00176 matd = egg_group->get_transform();
00177 } else {
00178 matd = LMatrix4d::ident_mat();
00179 }
00180
00181 LMatrix4f matf = LCAST(float, matd);
00182
00183 CharacterJoint *joint =
00184 new CharacterJoint(part, egg_group->get_name(), matf);
00185 index = _parts.size();
00186 _parts.push_back(joint);
00187
00188 if (egg_group->get_dcs_type() != EggGroup::DC_none) {
00189
00190
00191 joint->_geom_node = new PandaNode(egg_group->get_name());
00192 }
00193
00194 part = joint;
00195 }
00196
00197 EggGroup::const_iterator ci;
00198 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
00199 build_joint_hierarchy((*ci), part);
00200 }
00201 }
00202
00203 _node_map[egg_node] = index;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213 void CharacterMaker::
00214 parent_joint_nodes(PartGroup *part) {
00215 if (part->is_of_type(CharacterJoint::get_class_type())) {
00216 CharacterJoint *joint = DCAST(CharacterJoint, part);
00217 PandaNode *joint_node = joint->_geom_node;
00218 if (joint_node != NULL) {
00219 _character_node->add_child(joint_node);
00220 joint->add_net_transform(joint_node);
00221 joint_node->set_transform(TransformState::make_mat(joint->_net_transform));
00222 }
00223 }
00224
00225 for (int i = 0; i < part->get_num_children(); i++) {
00226 parent_joint_nodes(part->get_child(i));
00227 }
00228 }
00229
00230
00231
00232
00233
00234
00235 void CharacterMaker::
00236 make_geometry(EggNode *egg_node) {
00237 if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
00238 EggPrimitive *egg_primitive = DCAST(EggPrimitive, egg_node);
00239 if (!egg_primitive->empty()) {
00240 EggGroupNode *prim_home = determine_primitive_home(egg_primitive);
00241
00242 if (prim_home == NULL) {
00243
00244
00245 make_dynamic_primitive(egg_primitive, _egg_root);
00246
00247 } else {
00248
00249
00250 make_static_primitive(egg_primitive, prim_home);
00251 }
00252 }
00253 }
00254
00255 if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
00256 EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
00257
00258 EggGroupNode::const_iterator ci;
00259 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
00260 make_geometry(*ci);
00261 }
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270 void CharacterMaker::
00271 make_static_primitive(EggPrimitive *egg_primitive, EggGroupNode *prim_home) {
00272 PandaNode *node = part_to_node(egg_to_part(prim_home));
00273
00274
00275
00276 LMatrix4d transform =
00277 egg_primitive->get_vertex_frame() *
00278 prim_home->get_node_frame_inv();
00279
00280 _loader.make_nonindexed_primitive(egg_primitive, node, &transform);
00281 }
00282
00283
00284
00285
00286
00287
00288 void CharacterMaker::
00289 make_dynamic_primitive(EggPrimitive *egg_primitive, EggGroupNode *prim_home) {
00290 PandaNode *node = part_to_node(egg_to_part(prim_home));
00291
00292 LMatrix4d transform =
00293 egg_primitive->get_vertex_frame() *
00294 prim_home->get_node_frame_inv();
00295
00296 _loader.make_indexed_primitive(egg_primitive, node, &transform,
00297 _comp_verts_maker);
00298 }
00299
00300
00301
00302
00303
00304
00305 EggGroupNode *CharacterMaker::
00306 determine_primitive_home(EggPrimitive *egg_primitive) {
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 EggGroupNode *home = NULL;
00319
00320 EggPrimitive::const_iterator vi;
00321 for (vi = egg_primitive->begin();
00322 vi != egg_primitive->end();
00323 ++vi) {
00324 EggVertex *vertex = (*vi);
00325 if (vertex->gref_size() > 1) {
00326
00327
00328 return NULL;
00329 }
00330
00331 EggGroupNode *vertex_home;
00332
00333 if (vertex->gref_size() == 0) {
00334
00335
00336 vertex_home = egg_primitive->get_parent();
00337 } else {
00338 nassertr(vertex->gref_size() == 1, NULL);
00339
00340 vertex_home = *vertex->gref_begin();
00341 }
00342
00343 if (home != NULL && home != vertex_home) {
00344
00345
00346 return NULL;
00347 }
00348
00349 home = vertex_home;
00350 }
00351
00352
00353
00354 nassertr(home != NULL, NULL);
00355
00356
00357
00358
00359
00360
00361 EggGroup *egg_group = (EggGroup *)NULL;
00362 if (home->is_of_type(EggGroup::get_class_type())) {
00363 egg_group = DCAST(EggGroup, home);
00364 }
00365 while (egg_group != (EggGroup *)NULL &&
00366 egg_group->get_group_type() != EggGroup::GT_joint &&
00367 egg_group->get_dart_type() == EggGroup::DT_none) {
00368 nassertr(egg_group->get_parent() != (EggGroupNode *)NULL, NULL);
00369 home = egg_group->get_parent();
00370 egg_group = (EggGroup *)NULL;
00371 if (home->is_of_type(EggGroup::get_class_type())) {
00372 egg_group = DCAST(EggGroup, home);
00373 }
00374 }
00375
00376 if (egg_group != (EggGroup *)NULL &&
00377 egg_group->get_group_type() == EggGroup::GT_joint &&
00378 egg_group->get_dcs_type() == EggGroup::DC_none) {
00379
00380
00381
00382 return NULL;
00383 }
00384
00385
00386
00387
00388
00389 return home;
00390 }