00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "daeToEggConverter.h"
00016 #include "fcollada_utils.h"
00017 #include "config_daeegg.h"
00018 #include "daeCharacter.h"
00019 #include "dcast.h"
00020 #include "string_utils.h"
00021 #include "eggData.h"
00022 #include "eggPrimitive.h"
00023 #include "eggLine.h"
00024 #include "eggPolygon.h"
00025 #include "eggTriangleFan.h"
00026 #include "eggTriangleStrip.h"
00027 #include "eggPoint.h"
00028 #include "eggXfmSAnim.h"
00029 #include "eggSAnimData.h"
00030 #include "pt_EggVertex.h"
00031
00032 #include "FCDocument/FCDAsset.h"
00033 #include "FCDocument/FCDocumentTools.h"
00034 #include "FCDocument/FCDSceneNode.h"
00035 #include "FCDocument/FCDSceneNodeTools.h"
00036 #include "FCDocument/FCDGeometry.h"
00037 #include "FCDocument/FCDGeometryInstance.h"
00038 #include "FCDocument/FCDGeometryPolygons.h"
00039 #include "FCDocument/FCDGeometrySource.h"
00040 #include "FCDocument/FCDSkinController.h"
00041 #include "FCDocument/FCDController.h"
00042 #include "FCDocument/FCDControllerInstance.h"
00043 #include "FCDocument/FCDMorphController.h"
00044 #include "FCDocument/FCDMaterialInstance.h"
00045 #include "FCDocument/FCDExtra.h"
00046 #include "FCDocument/FCDEffect.h"
00047 #include "FCDocument/FCDEffectStandard.h"
00048 #if FCOLLADA_VERSION >= 0x00030005
00049 #include "FCDocument/FCDGeometryPolygonsInput.h"
00050 #endif
00051
00052
00053
00054
00055
00056
00057 DAEToEggConverter::
00058 DAEToEggConverter() {
00059 _document = NULL;
00060 _table = NULL;
00061 _frame_rate = -1;
00062 _error_handler = NULL;
00063 }
00064
00065
00066
00067
00068
00069
00070 DAEToEggConverter::
00071 DAEToEggConverter(const DAEToEggConverter ©) :
00072 SomethingToEggConverter(copy)
00073 {
00074 }
00075
00076
00077
00078
00079
00080
00081 DAEToEggConverter::
00082 ~DAEToEggConverter() {
00083 if (_error_handler != NULL) {
00084 delete _error_handler;
00085 }
00086 }
00087
00088
00089
00090
00091
00092
00093 SomethingToEggConverter *DAEToEggConverter::
00094 make_copy() {
00095 return new DAEToEggConverter(*this);
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105 string DAEToEggConverter::
00106 get_name() const {
00107 return "COLLADA";
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 string DAEToEggConverter::
00117 get_extension() const {
00118 return "dae";
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128 bool DAEToEggConverter::
00129 convert_file(const Filename &filename) {
00130
00131 clear_error();
00132 _joints.clear();
00133 _vertex_pools.clear();
00134 _skeletons.clear();
00135 _frame_rate = -1;
00136 if (_error_handler == NULL) {
00137 _error_handler = new FUErrorSimpleHandler;
00138 }
00139
00140
00141 if (_egg_data->get_coordinate_system() == CS_default) {
00142 _egg_data->set_coordinate_system(CS_yup_right);
00143 }
00144
00145
00146 FCollada::Initialize();
00147 _document = FCollada::LoadDocument(filename.to_os_specific().c_str());
00148 if (_document == NULL) {
00149 daeegg_cat.error() << "Failed to load document: " << _error_handler->GetErrorString() << endl;
00150 FCollada::Release();
00151 return false;
00152 }
00153
00154 if (_document->GetAsset() != NULL) {
00155 FCDocumentTools::StandardizeUpAxisAndLength(_document);
00156 }
00157
00158 _table = new EggTable();
00159 _table->set_table_type(EggTable::TT_table);
00160
00161 process_asset();
00162 preprocess();
00163 FCDSceneNode* visual_scene = _document->GetVisualSceneInstance();
00164 if (visual_scene != NULL) {
00165
00166 const FCDExtra* extra = visual_scene->GetExtra();
00167
00168 if (extra != NULL) {
00169 const FCDEType* etype = extra->GetDefaultType();
00170 if (etype != NULL) {
00171 const FCDENode* enode = (const FCDENode*) etype->FindTechnique("MAX3D");
00172 if (enode != NULL) {
00173 enode = enode->FindChildNode("frame_rate");
00174 if (enode != NULL && !string_to_int(enode->GetContent(), _frame_rate)) {
00175 daeegg_cat.warning() << "Invalid integer in <frame_rate> tag: '" << enode->GetContent() << "'" << endl;
00176 } } } }
00177
00178 for (size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
00179 process_node(DCAST(EggGroupNode, _egg_data), visual_scene->GetChild(ch));
00180 }
00181 }
00182 SAFE_DELETE(visual_scene);
00183
00184 _egg_data->add_child(_table);
00185
00186
00187 SAFE_DELETE(_document);
00188 FCollada::Release();
00189 return true;
00190 }
00191
00192 void DAEToEggConverter::process_asset() {
00193 if (_document->GetAsset() == NULL) return;
00194
00195 FMVector3 up_axis (_document->GetAsset()->GetUpAxis());
00196 if (up_axis == FMVector3(0, 1, 0)) {
00197 _egg_data->set_coordinate_system(CS_yup_right);
00198 } else if (up_axis == FMVector3(0, 0, 1)) {
00199 _egg_data->set_coordinate_system(CS_zup_right);
00200 } else {
00201 _egg_data->set_coordinate_system(CS_invalid);
00202 daeegg_cat.warning() << "Unrecognized coordinate system!\n";
00203 }
00204 }
00205
00206
00207 void DAEToEggConverter::preprocess(const FCDSceneNode* node) {
00208
00209 if (node == NULL) {
00210 assert(_document != NULL);
00211 _skeletons.clear();
00212 _joints.clear();
00213 node = _document->GetVisualSceneInstance();
00214 }
00215 if (node == NULL) return;
00216 if (node->IsJoint()) {
00217 _joints[FROM_FSTRING(node->GetDaeId())] = NULL;
00218 }
00219
00220 for (size_t in = 0; in < node->GetInstanceCount(); ++in) {
00221 if (node->GetInstance(in)->GetType() == FCDEntityInstance::CONTROLLER) {
00222
00223 #if FCOLLADA_VERSION < 0x00030005
00224 FCDSceneNodeList roots = ((FCDControllerInstance*) node->GetInstance(in))->FindSkeletonNodes();
00225 #else
00226 FCDSceneNodeList roots;
00227 ((FCDControllerInstance*) node->GetInstance(in))->FindSkeletonNodes(roots);
00228 #endif
00229 for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
00230 daeegg_cat.spam() << "Found referenced skeleton root " << FROM_FSTRING((*it)->GetDaeId()) << endl;
00231 _skeletons.push_back(FROM_FSTRING((*it)->GetDaeId()));
00232 }
00233 }
00234 }
00235
00236 for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
00237 preprocess(node->GetChild(ch));
00238 }
00239 }
00240
00241
00242 void DAEToEggConverter::process_node(PT(EggGroupNode) parent, const FCDSceneNode* node, bool forced) {
00243 nassertv(node != NULL);
00244 string node_id = FROM_FSTRING(node->GetDaeId());
00245 daeegg_cat.spam() << "Processing node with ID '" << node_id << "'" << endl;
00246
00247 if (!forced && count(_skeletons.begin(), _skeletons.end(), node_id) > 0) {
00248 daeegg_cat.spam() << "Ignoring skeleton root node with ID '" << node_id << "', we'll process it later" << endl;
00249 return;
00250 }
00251
00252 PT(EggGroup) node_group = new EggGroup(FROM_FSTRING(node->GetName()));
00253 process_extra(node_group, node->GetExtra());
00254 parent->add_child(node_group);
00255
00256 if (node->IsJoint()) {
00257 node_group->set_group_type(EggGroup::GT_joint);
00258 _joints[node_id] = node_group;
00259 }
00260
00261 for (size_t tr = 0; tr < node->GetTransformCount(); ++tr) {
00262 apply_transform(node_group, node->GetTransform(tr));
00263 }
00264
00265 for (size_t in = 0; in < node->GetInstanceCount(); ++in) {
00266 process_instance(node_group, node->GetInstance(in));
00267 }
00268
00269 for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
00270 process_node(DCAST(EggGroupNode, node_group), node->GetChild(ch));
00271 }
00272
00273 for (size_t in = 0; in < node->GetInstanceCount(); ++in) {
00274 if (node->GetInstance(in)->GetEntity() && node->GetInstance(in)->GetEntity()->GetType() == FCDEntity::SCENE_NODE) {
00275 process_node(DCAST(EggGroupNode, node_group), (const FCDSceneNode*) node->GetInstance(in)->GetEntity());
00276 }
00277 }
00278 }
00279
00280 void DAEToEggConverter::process_instance(PT(EggGroup) parent, const FCDEntityInstance* instance) {
00281 nassertv(instance != NULL);
00282 nassertv(instance->GetEntity() != NULL);
00283
00284 switch (instance->GetType()) {
00285 case FCDEntityInstance::GEOMETRY: {
00286 const FCDGeometry* geometry = (const FCDGeometry*) instance->GetEntity();
00287 assert(geometry != NULL);
00288 if (geometry->IsMesh()) {
00289
00290 process_mesh(parent, geometry->GetMesh(), new DaeMaterials((const FCDGeometryInstance*) instance));
00291 }
00292 if (geometry->IsSpline()) {
00293 process_spline(parent, FROM_FSTRING(geometry->GetName()), const_cast<FCDGeometrySpline*> (geometry->GetSpline()));
00294 }
00295 break; }
00296 case FCDEntityInstance::CONTROLLER: {
00297
00298 parent->set_dart_type(EggGroup::DT_default);
00299 process_controller(parent, (const FCDControllerInstance*) instance);
00300 break; }
00301 case FCDEntityInstance::MATERIAL:
00302
00303 break;
00304 case FCDEntityInstance::SIMPLE: {
00305
00306 const FCDEntity* entity = instance->GetEntity();
00307 if (entity->GetType() != FCDEntity::SCENE_NODE) {
00308 daeegg_cat.warning() << "Unsupported entity type found" << endl;
00309 }
00310 break; }
00311 default:
00312 daeegg_cat.warning() << "Unsupported instance type found" << endl;
00313 }
00314 }
00315
00316
00317 void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh* mesh, PT(DaeMaterials) materials) {
00318 nassertv(mesh != NULL);
00319 daeegg_cat.debug() << "Processing mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << endl;
00320
00321
00322 PT(EggGroup) mesh_group = new EggGroup(FROM_FSTRING(mesh->GetDaeId()));
00323 parent->add_child(mesh_group);
00324 PT(EggVertexPool) mesh_pool = new EggVertexPool(FROM_FSTRING(mesh->GetDaeId()));
00325 mesh_group->add_child(mesh_pool);
00326 _vertex_pools[FROM_FSTRING(mesh->GetDaeId())] = mesh_pool;
00327
00328
00329 if (mesh->GetSourceCount() == 0) {
00330 daeegg_cat.debug() << "Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << " has no sources" << endl;
00331 return;
00332 }
00333 const FCDGeometrySource* vsource = mesh->FindSourceByType(FUDaeGeometryInput::POSITION);
00334 if (vsource == NULL) {
00335 daeegg_cat.debug() << "Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << " has no source for POSITION data" << endl;
00336 return;
00337 }
00338
00339
00340 daeegg_cat.spam() << "Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << " has " << mesh->GetPolygonsCount() << " polygon groups" << endl;
00341 if (mesh->GetPolygonsCount() == 0) return;
00342
00343
00344 PT(EggGroup) *primitive_holders = new PT(EggGroup) [mesh->GetPolygonsCount()];
00345 for (size_t gr = 0; gr < mesh->GetPolygonsCount(); ++gr) {
00346 const FCDGeometryPolygons* polygons = mesh->GetPolygons(gr);
00347
00348 PT(EggGroup) primitiveholder;
00349
00350 if (materials != NULL && (!polygons->GetMaterialSemantic().empty()) && mesh->GetPolygonsCount() > 1) {
00351 primitiveholder = new EggGroup(FROM_FSTRING(mesh->GetDaeId()) + "." + FROM_FSTRING(polygons->GetMaterialSemantic()));
00352 mesh_group->add_child(primitiveholder);
00353 } else {
00354 primitiveholder = mesh_group;
00355 }
00356 primitive_holders[gr] = primitiveholder;
00357
00358 if (materials != NULL) {
00359 materials->apply_to(FROM_FSTRING(polygons->GetMaterialSemantic()), primitiveholder);
00360 }
00361
00362 const FCDGeometryPolygonsInput* pinput = polygons->FindInput(FUDaeGeometryInput::POSITION);
00363 assert(pinput != NULL);
00364 const uint32* indices = pinput->GetIndices();
00365
00366 const FCDGeometrySource* nsource = mesh->FindSourceByType(FUDaeGeometryInput::NORMAL);
00367 const FCDGeometryPolygonsInput* ninput = polygons->FindInput(FUDaeGeometryInput::NORMAL);
00368 const uint32* nindices;
00369 if (ninput != NULL) nindices = ninput->GetIndices();
00370
00371 const FCDGeometrySource* tcsource = mesh->FindSourceByType(FUDaeGeometryInput::TEXCOORD);
00372 const FCDGeometryPolygonsInput* tcinput = polygons->FindInput(FUDaeGeometryInput::TEXCOORD);
00373 const uint32* tcindices;
00374 if (tcinput != NULL) tcindices = tcinput->GetIndices();
00375
00376 const FCDGeometrySource* csource = mesh->FindSourceByType(FUDaeGeometryInput::COLOR);
00377 const FCDGeometryPolygonsInput* cinput = polygons->FindInput(FUDaeGeometryInput::COLOR);
00378 const uint32* cindices;
00379 if (cinput != NULL) cindices = cinput->GetIndices();
00380
00381 const FCDGeometrySource* bsource = mesh->FindSourceByType(FUDaeGeometryInput::TEXBINORMAL);
00382 const FCDGeometryPolygonsInput* binput = polygons->FindInput(FUDaeGeometryInput::TEXBINORMAL);
00383 const uint32* bindices;
00384 if (binput != NULL) bindices = binput->GetIndices();
00385
00386 const FCDGeometrySource* tsource = mesh->FindSourceByType(FUDaeGeometryInput::TEXTANGENT);
00387 const FCDGeometryPolygonsInput* tinput = polygons->FindInput(FUDaeGeometryInput::TEXTANGENT);
00388 const uint32* tindices;
00389 if (tinput != NULL) tindices = tinput->GetIndices();
00390
00391 string tcsetname ("");
00392 if (materials != NULL && tcinput != NULL) {
00393 daeegg_cat.debug() << "Assigning texcoord set " << tcinput->GetSet() << " to semantic '" << FROM_FSTRING(polygons->GetMaterialSemantic()) << "'\n";
00394 tcsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXCOORD, tcinput->GetSet());
00395 }
00396 string tbsetname ("");
00397 if (materials != NULL && binput != NULL) {
00398 daeegg_cat.debug() << "Assigning texbinormal set " << binput->GetSet() << " to semantic '" << FROM_FSTRING(polygons->GetMaterialSemantic()) << "'\n";
00399 tbsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXBINORMAL, binput->GetSet());
00400 }
00401 string ttsetname ("");
00402 if (materials != NULL && tinput != NULL) {
00403 daeegg_cat.debug() << "Assigning textangent set " << tinput->GetSet() << " to semantic '" << FROM_FSTRING(polygons->GetMaterialSemantic()) << "'\n";
00404 ttsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXTANGENT, tinput->GetSet());
00405 }
00406
00407 for (size_t ix = 0; ix < pinput->GetIndexCount(); ++ix) {
00408 PT_EggVertex vertex = mesh_pool->make_new_vertex();
00409 const float* data = &vsource->GetData()[indices[ix]*3];
00410 vertex->set_pos(LPoint3d(data[0], data[1], data[2]));
00411
00412 if (nsource != NULL && ninput != NULL) {
00413 assert(nsource->GetStride() == 3);
00414 data = &nsource->GetData()[nindices[ix]*3];
00415 vertex->set_normal(LVecBase3d(data[0], data[1], data[2]));
00416 }
00417
00418 if (tcsource != NULL && tcinput != NULL) {
00419 assert(tcsource->GetStride() == 2 || tcsource->GetStride() == 3);
00420 data = &tcsource->GetData()[tcindices[ix]*tcsource->GetStride()];
00421 if (tcsource->GetStride() == 2) {
00422 vertex->set_uv(tcsetname, LPoint2d(data[0], data[1]));
00423 } else {
00424 vertex->set_uvw(tcsetname, LPoint3d(data[0], data[1], data[2]));
00425 }
00426 }
00427
00428 if (csource != NULL && cinput != NULL) {
00429 assert(csource->GetStride() == 3 || csource->GetStride() == 4);
00430 if (csource->GetStride() == 3) {
00431 data = &csource->GetData()[cindices[ix]*3];
00432 vertex->set_color(LColor(data[0], data[1], data[2], 1.0f));
00433 } else {
00434 data = &csource->GetData()[cindices[ix]*4];
00435 vertex->set_color(LColor(data[0], data[1], data[2], data[3]));
00436 }
00437 }
00438
00439 if ((bsource != NULL && binput != NULL) || (tsource != NULL && tinput != NULL)) {
00440 if (bsource != NULL && binput != NULL) {
00441 assert(bsource->GetStride() == 3);
00442 data = &bsource->GetData()[bindices[ix]*3];
00443 PT(EggVertexUV) uv_obj = vertex->modify_uv_obj(tbsetname);
00444 if (uv_obj == NULL) {
00445 uv_obj = new EggVertexUV(tbsetname, LTexCoordd());
00446 }
00447 uv_obj->set_binormal(LVecBase3d(data[0], data[1], data[2]));
00448 }
00449 if (tsource != NULL && tinput != NULL) {
00450 assert(tsource->GetStride() == 3);
00451 data = &tsource->GetData()[tindices[ix]*3];
00452 PT(EggVertexUV) uv_obj = vertex->modify_uv_obj(ttsetname);
00453 if (uv_obj == NULL) {
00454 uv_obj = new EggVertexUV(ttsetname, LTexCoordd());
00455 }
00456 uv_obj->set_tangent(LVecBase3d(data[0], data[1], data[2]));
00457 }
00458 }
00459 vertex->transform(parent->get_node_to_vertex());
00460 }
00461 }
00462
00463 for (size_t gr = 0; gr < mesh->GetPolygonsCount(); ++gr) {
00464 const FCDGeometryPolygons* polygons = mesh->GetPolygons(gr);
00465
00466 uint32 offset = 0;
00467 for (size_t fa = 0; fa < polygons->GetFaceVertexCountCount(); ++fa) {
00468 PT(EggPrimitive) primitive = NULL;
00469
00470 switch (polygons->GetPrimitiveType()) {
00471 case FCDGeometryPolygons::LINES:
00472 primitive = new EggLine();
00473 break;
00474 case FCDGeometryPolygons::POLYGONS:
00475 primitive = new EggPolygon();
00476 break;
00477 case FCDGeometryPolygons::TRIANGLE_FANS:
00478 primitive = new EggTriangleFan();
00479 break;
00480 case FCDGeometryPolygons::TRIANGLE_STRIPS:
00481 primitive = new EggTriangleStrip();
00482 break;
00483 case FCDGeometryPolygons::POINTS:
00484 primitive = new EggPoint();
00485 break;
00486 case FCDGeometryPolygons::LINE_STRIPS:
00487 daeegg_cat.warning() << "Linestrips not yet supported!" << endl;
00488 break;
00489 default:
00490 daeegg_cat.warning() << "Unsupported primitive type found!" << endl;
00491 }
00492 if (primitive != NULL) {
00493 primitive_holders[gr]->add_child(primitive);
00494 if (materials != NULL) {
00495 materials->apply_to(FROM_FSTRING(polygons->GetMaterialSemantic()), primitive);
00496 }
00497 for (size_t ve = 0; ve < polygons->GetFaceVertexCount(fa); ++ve) {
00498 assert(mesh_pool->has_vertex(ve + polygons->GetFaceVertexOffset() + offset));
00499 primitive->add_vertex(mesh_pool->get_vertex(ve + polygons->GetFaceVertexOffset() + offset));
00500 }
00501 }
00502 offset += polygons->GetFaceVertexCount(fa);
00503 }
00504 }
00505 delete[] primitive_holders;
00506 }
00507
00508 void DAEToEggConverter::process_spline(PT(EggGroup) parent, const string group_name, FCDGeometrySpline* geometry_spline) {
00509 assert(geometry_spline != NULL);
00510 PT(EggGroup) result = new EggGroup(group_name);
00511 parent->add_child(result);
00512
00513 if (geometry_spline->GetType() != FUDaeSplineType::NURBS) {
00514 daeegg_cat.warning() << "Only NURBS curves are supported (yet)!" << endl;
00515 } else {
00516
00517 for (size_t sp = 0; sp < geometry_spline->GetSplineCount(); ++sp) {
00518 process_spline(result, geometry_spline->GetSpline(sp));
00519 }
00520 }
00521 }
00522
00523 void DAEToEggConverter::process_spline(PT(EggGroup) parent, const FCDSpline* spline) {
00524 assert(spline != NULL);
00525 nassertv(spline->GetSplineType() == FUDaeSplineType::NURBS);
00526
00527 PT(EggNurbsCurve) nurbs_curve = new EggNurbsCurve(FROM_FSTRING(spline->GetName()));
00528 parent->add_child(nurbs_curve);
00529
00530 nurbs_curve->setup(0, ((const FCDNURBSSpline*) spline)->GetKnotCount());
00531 for (size_t kn = 0; kn < ((const FCDNURBSSpline*) spline)->GetKnotCount(); ++kn) {
00532 const float* knot = ((const FCDNURBSSpline*) spline)->GetKnot(kn);
00533 assert(knot != NULL);
00534 nurbs_curve->set_knot(kn, *knot);
00535 }
00536 for (size_t cv = 0; cv < spline->GetCVCount(); ++cv) {
00537 PT_EggVertex c_vtx = new EggVertex();
00538 c_vtx->set_pos(TO_VEC3(*spline->GetCV(cv)));
00539 c_vtx->transform(parent->get_node_to_vertex());
00540 nurbs_curve->add_vertex(c_vtx);
00541 }
00542 }
00543
00544 void DAEToEggConverter::process_controller(PT(EggGroup) parent, const FCDControllerInstance* instance) {
00545 assert(instance != NULL);
00546 const FCDController* controller = (const FCDController*) instance->GetEntity();
00547 assert(controller != NULL);
00548 PT(EggVertexPool) vertex_pool = NULL;
00549
00550 const FCDGeometry* geometry = controller->GetBaseGeometry();
00551 if (geometry != NULL) {
00552 if (geometry->IsMesh()) {
00553 process_mesh(parent, geometry->GetMesh(), new DaeMaterials((const FCDGeometryInstance*) instance));
00554 daeegg_cat.spam() << "Processing mesh for controller\n";
00555 if (_vertex_pools.count(FROM_FSTRING(geometry->GetMesh()->GetDaeId()))) {
00556 daeegg_cat.debug() << "Using vertex pool " << FROM_FSTRING(geometry->GetMesh()->GetDaeId()) << "\n";
00557 vertex_pool = _vertex_pools[FROM_FSTRING(geometry->GetMesh()->GetDaeId())];
00558 }
00559 }
00560 if (geometry->IsSpline()) {
00561 process_spline(parent, FROM_FSTRING(geometry->GetName()), const_cast<FCDGeometrySpline*> (geometry->GetSpline()));
00562 }
00563 }
00564
00565 #if FCOLLADA_VERSION < 0x00030005
00566 FCDSceneNodeList roots = (const_cast<FCDControllerInstance*> (instance))->FindSkeletonNodes();
00567 #else
00568 FCDSceneNodeList roots;
00569 (const_cast<FCDControllerInstance*> (instance))->FindSkeletonNodes(roots);
00570 #endif
00571 for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
00572 process_node(DCAST(EggGroupNode, parent), *it, true);
00573 }
00574 if (controller->IsSkin()) {
00575
00576 pmap<int32, pvector<pair<PT_EggVertex, PN_stdfloat> > > influences;
00577 if (vertex_pool) {
00578 for (size_t in = 0; in < controller->GetSkinController()->GetInfluenceCount(); ++in) {
00579 assert(vertex_pool->has_vertex(in));
00580 for (size_t pa = 0; pa < controller->GetSkinController()->GetVertexInfluence(in)->GetPairCount(); ++pa) {
00581 const FCDJointWeightPair* jwpair = controller->GetSkinController()->GetVertexInfluence(in)->GetPair(pa);
00582 influences[jwpair->jointIndex].push_back(pair<PT_EggVertex, PN_stdfloat> (vertex_pool->get_vertex(in), jwpair->weight));
00583 }
00584 }
00585 }
00586
00587 for (pmap<int32, pvector<pair<PT_EggVertex, PN_stdfloat> > >::iterator it = influences.begin(); it != influences.end(); ++it) {
00588 if (it->first == -1) {
00589 daeegg_cat.warning() << "Ignoring vertex influence with negative joint index\n";
00590
00591 } else {
00592 const string joint_id = FROM_FSTRING(controller->GetSkinController()->GetJoint(it->first)->GetId());
00593
00594 if (_joints.count(joint_id) > 0) {
00595 if (_joints[joint_id]) {
00596 for (pvector<pair<PT_EggVertex, PN_stdfloat> >::iterator vi = it->second.begin(); vi != it->second.end(); ++vi) {
00597 _joints[joint_id]->ref_vertex(vi->first, vi->second);
00598 }
00599 } else {
00600 daeegg_cat.warning() << "Unprocessed joint being referenced: '" << joint_id << "'" << endl;
00601 }
00602 } else {
00603 daeegg_cat.warning() << "Unknown joint being referenced: '" << joint_id << "'" << endl;
00604 }
00605 }
00606 }
00607 }
00608 if (controller->IsMorph()) {
00609 assert(controller != NULL);
00610 const FCDMorphController* morph_controller = controller->GetMorphController();
00611 assert(morph_controller != NULL);
00612 PT(EggTable) bundle = new EggTable(parent->get_name());
00613 bundle->set_table_type(EggTable::TT_bundle);
00614 PT(EggTable) morph = new EggTable("morph");
00615 morph->set_table_type(EggTable::TT_table);
00616 bundle->add_child(morph);
00617
00618 for (size_t mt = 0; mt < morph_controller->GetTargetCount(); ++mt) {
00619 const FCDMorphTarget* morph_target = morph_controller->GetTarget(mt);
00620 assert(morph_target != NULL);
00621 PT(EggSAnimData) target = new EggSAnimData(FROM_FSTRING(morph_target->GetGeometry()->GetName()));
00622 if (morph_target->IsAnimated()) {
00623
00624 } else {
00625 target->add_data(morph_target->GetWeight());
00626 }
00627 morph->add_child(target);
00628 }
00629 }
00630
00631
00632 PT(DaeCharacter) character = new DaeCharacter(parent->get_name(), instance);
00633 _table->add_child(character->as_egg_bundle());
00634 }
00635
00636 void DAEToEggConverter::process_extra(PT(EggGroup) group, const FCDExtra* extra) {
00637 if (extra == NULL) {
00638 return;
00639 }
00640 nassertv(group != NULL);
00641
00642 const FCDEType* etype = extra->GetDefaultType();
00643 if (etype == NULL) {
00644 return;
00645 }
00646
00647 const FCDENode* enode = (const FCDENode*) etype->FindTechnique("PANDA3D");
00648 if (enode == NULL) {
00649 return;
00650 }
00651
00652 FCDENodeList tags;
00653 enode->FindChildrenNodes("param", tags);
00654 for (FCDENodeList::iterator it = tags.begin(); it != tags.end(); ++it) {
00655 const FCDEAttribute* attr = (*it)->FindAttribute("sid");
00656 if (attr) {
00657 group->set_tag(FROM_FSTRING(attr->GetValue()), (*it)->GetContent());
00658 }
00659 }
00660 }
00661
00662 LMatrix4d DAEToEggConverter::convert_matrix(const FMMatrix44& matrix) {
00663 LMatrix4d result = LMatrix4d::zeros_mat();
00664 for (char x = 0; x < 4; ++x) {
00665 for (char y = 0; y < 4; ++y) {
00666 result(x, y) = matrix[x][y];
00667 }
00668 }
00669 return result;
00670 }
00671
00672 void DAEToEggConverter::apply_transform(const PT(EggGroup) to, const FCDTransform* from) {
00673 assert(from != NULL);
00674 assert(to != NULL);
00675 to->set_transform3d(convert_matrix(from->ToMatrix()) * to->get_transform3d());
00676 }