00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <vlGraphics/plugins/COLLADA/DaeLoader.hpp>
00033 #include <vlGraphics/GeometryPrimitives.hpp>
00034
00035 using namespace vl;
00036
00037 namespace
00038 {
00039
00040 const char* VL_NO_MATERIAL_SPECIFIED = "<VL_NO_MATERIAL_SPECIFIED>";
00041 const char* VL_DEFAULT_LIGHT = "<VL_DEFAULT_LIGHT>";
00042
00043 struct
00044 {
00045 Dae::EInputSemantic mSemantic;
00046 const char* mSemanticString;
00047 } SemanticTable[] =
00048 {
00049 { Dae::IS_UNKNOWN, "UNKNOWN" },
00050 { Dae::IS_BINORMAL, "BINORMAL" },
00051 { Dae::IS_COLOR, "COLOR" },
00052 { Dae::IS_CONTINUITY, "CONTINUITY" },
00053 { Dae::IS_IMAGE, "IMAGE" },
00054 { Dae::IS_INPUT, "INPUT" },
00055 { Dae::IS_IN_TANGENT, "IN_TANGENT" },
00056 { Dae::IS_INTERPOLATION, "INTERPOLATION" },
00057 { Dae::IS_INV_BIND_MATRIX, "INV_BIND_MATRIX" },
00058 { Dae::IS_JOINT, "JOINT" },
00059 { Dae::IS_LINEAR_STEPS, "LINEAR_STEPS" },
00060 { Dae::IS_MORPHS_TARGET, "MORPHS_TARGET" },
00061 { Dae::IS_MORPH_WEIGHT, "MORPH_WEIGHT" },
00062 { Dae::IS_NORMAL, "NORMAL" },
00063 { Dae::IS_OUTPUT, "OUTPUT" },
00064 { Dae::IS_OUT_TANGENT, "OUT_TANGENT" },
00065 { Dae::IS_POSITION, "POSITION" },
00066 { Dae::IS_TANGENT, "TANGENT" },
00067 { Dae::IS_TEXBINORMAL, "TEXBINORMAL" },
00068 { Dae::IS_TEXCOORD, "TEXCOORD" },
00069 { Dae::IS_TEXTANGENT, "TEXTANGENT" },
00070 { Dae::IS_UV, "UV" },
00071 { Dae::IS_VERTEX, "VERTEX" },
00072 { Dae::IS_WEIGHT, "WEIGHT" },
00073 { Dae::IS_UNKNOWN, NULL }
00074 };
00075 }
00076
00077 DaeLoader::DaeLoader()
00078 {
00079 reset();
00080
00081
00082
00083 mDefaultFX = new Effect;
00084 mDefaultFX->setObjectName( VL_NO_MATERIAL_SPECIFIED );
00085 mDefaultFX->shader()->enable(EN_LIGHTING);
00086 mDefaultFX->shader()->setRenderState( new Light, 0 );
00087 mDefaultFX->shader()->gocMaterial()->setFlatColor( vl::fuchsia );
00088 mDefaultFX->shader()->gocPolygonMode()->set(PM_LINE, PM_LINE);
00089 }
00090
00091 void DaeLoader::reset()
00092 {
00093 mAssumeOpaque = false;
00094 mInvertTransparency = false;
00095 mScene = NULL;
00096 mResources = new ResourceDatabase;
00097 }
00098
00099 void DaeLoader::parseInputs(Dae::Primitive* dae_primitive, const domInputLocalOffset_Array& input_arr, const std::vector< ref<Dae::Input> >& vertex_inputs)
00100 {
00101 dae_primitive->mIndexStride = 0;
00102
00103 for(size_t iinp=0; iinp<input_arr.getCount(); ++iinp)
00104 {
00105 domInputLocalOffsetRef input = input_arr.get(iinp);
00106
00107
00108 if ( getSemantic(input->getSemantic()) == Dae::IS_VERTEX )
00109 {
00110 VL_CHECK(!vertex_inputs.empty())
00111 for(size_t ivert=0; ivert<vertex_inputs.size(); ++ivert)
00112 {
00113 ref<Dae::Input> dae_input = new Dae::Input;
00114 dae_input->mSemantic = vertex_inputs[ivert]->mSemantic;
00115 dae_input->mSource = vertex_inputs[ivert]->mSource;
00116 dae_input->mOffset = (size_t)input->getOffset();
00117 dae_input->mSet = (size_t)input->getSet();
00118 dae_primitive->mChannels.push_back(dae_input);
00119
00120 VL_CHECK(dae_input->mSource);
00121 VL_CHECK(dae_input->mSemantic != Dae::IS_UNKNOWN);
00122
00123
00124 dae_primitive->mIndexStride = std::max(dae_primitive->mIndexStride, dae_input->mOffset);
00125 }
00126 }
00127 else
00128 {
00129 ref<Dae::Input> dae_input = new Dae::Input;
00130 dae_input->mSemantic = getSemantic(input->getSemantic());
00131 dae_input->mSource = getSource( input->getSource().getElement() );
00132 dae_input->mOffset = (size_t)input->getOffset();
00133 dae_input->mSet = (size_t)input->getSet();
00134
00135
00136 if (dae_input->mSource)
00137 dae_primitive->mChannels.push_back( dae_input );
00138
00139 VL_CHECK(dae_input->mSource);
00140 VL_CHECK(dae_input->mSemantic != Dae::IS_UNKNOWN);
00141
00142 dae_primitive->mIndexStride = std::max(dae_primitive->mIndexStride, dae_input->mOffset);
00143 }
00144 }
00145
00146 dae_primitive->mIndexStride += 1;
00147 }
00148
00149 ref<Dae::Mesh> DaeLoader::parseGeometry(daeElement* geometry)
00150 {
00151
00152 std::map< daeElementRef, ref<Dae::Mesh> >::iterator it = mMeshes.find( geometry );
00153 if (it != mMeshes.end())
00154 return it->second;
00155
00156 if (!geometry->getChild("mesh"))
00157 return NULL;
00158
00159 domMesh* mesh = static_cast<domMesh*>(geometry->getChild("mesh"));
00160
00161
00162 ref<Dae::Mesh> dae_mesh = new Dae::Mesh;
00163 mMeshes[geometry] = dae_mesh;
00164
00165
00166 domVerticesRef vertices = mesh->getVertices();
00167 domInputLocal_Array input_array = vertices->getInput_array();
00168 for(size_t i=0; i<input_array.getCount(); ++i)
00169 {
00170 ref<Dae::Input> dae_input = new Dae::Input;
00171
00172 dae_input->mSemantic = getSemantic(input_array[i]->getSemantic());
00173 if (dae_input->mSemantic == Dae::IS_UNKNOWN)
00174 {
00175 Log::error( Say("LoadWriterDae: the following semantic is unknown: %s\n") << input_array[i]->getSemantic() );
00176 continue;
00177 }
00178
00179 dae_input->mSource = getSource( input_array[i]->getSource().getElement() );
00180
00181 if (!dae_input->mSource)
00182 continue;
00183
00184 dae_mesh->mVertexInputs.push_back(dae_input);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194 domTriangles_Array triangles_arr = mesh->getTriangles_array();
00195 for(size_t itri=0; itri< triangles_arr.getCount(); ++itri)
00196 {
00197 domTrianglesRef triangles = triangles_arr.get(itri);
00198
00199 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00200 dae_mesh->mPrimitives.push_back(dae_primitive);
00201 dae_primitive->mType = Dae::PT_TRIANGLES;
00202 dae_primitive->mCount = (size_t)triangles->getCount();
00203
00204
00205 domInputLocalOffset_Array input_arr = triangles->getInput_array();
00206 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00207
00208
00209 dae_primitive->mP.push_back( triangles->getP() );
00210
00211
00212 dae_primitive->mMaterial = triangles->getMaterial() ? triangles->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00213
00214
00215 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00216 }
00217
00218
00219 domTrifans_Array trifan_arr = mesh->getTrifans_array();
00220 for(size_t itri=0; itri< trifan_arr.getCount(); ++itri)
00221 {
00222 domTrifansRef trifan = trifan_arr.get(itri);
00223
00224 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00225 dae_mesh->mPrimitives.push_back(dae_primitive);
00226 dae_primitive->mType = Dae::PT_TRIFANS;
00227 dae_primitive->mCount = (size_t)trifan->getCount();
00228
00229
00230 domInputLocalOffset_Array input_arr = trifan->getInput_array();
00231 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00232
00233
00234 for(size_t ip=0; ip<trifan->getP_array().getCount(); ++ip)
00235 dae_primitive->mP.push_back( trifan->getP_array().get(ip) );
00236
00237
00238 dae_primitive->mMaterial = trifan->getMaterial() ? trifan->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00239
00240
00241 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00242 }
00243
00244
00245 domTristrips_Array tristrip_arr = mesh->getTristrips_array();
00246 for(size_t itri=0; itri< tristrip_arr.getCount(); ++itri)
00247 {
00248 domTristripsRef tristrip = tristrip_arr.get(itri);
00249
00250 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00251 dae_mesh->mPrimitives.push_back(dae_primitive);
00252 dae_primitive->mType = Dae::PT_TRISTRIPS;
00253 dae_primitive->mCount = (size_t)tristrip->getCount();
00254
00255
00256 domInputLocalOffset_Array input_arr = tristrip->getInput_array();
00257 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00258
00259
00260 for(size_t ip=0; ip<tristrip->getP_array().getCount(); ++ip)
00261 dae_primitive->mP.push_back( tristrip->getP_array().get(ip) );
00262
00263
00264 dae_primitive->mMaterial = tristrip->getMaterial() ? tristrip->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00265
00266
00267 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00268 }
00269
00270
00271 domPolygons_Array polygon_arr = mesh->getPolygons_array();
00272 for(size_t itri=0; itri< polygon_arr.getCount(); ++itri)
00273 {
00274 domPolygonsRef polygon = polygon_arr.get(itri);
00275
00276 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00277 dae_mesh->mPrimitives.push_back(dae_primitive);
00278 dae_primitive->mType = Dae::PT_POLYGONS;
00279 dae_primitive->mCount = (size_t)polygon->getCount();
00280
00281
00282 domInputLocalOffset_Array input_arr = polygon->getInput_array();
00283 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00284
00285
00286 for(size_t ip=0; ip<polygon->getP_array().getCount(); ++ip)
00287 dae_primitive->mP.push_back( polygon->getP_array().get(ip) );
00288
00289
00290 dae_primitive->mMaterial = polygon->getMaterial() ? polygon->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00291
00292
00293 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00294 }
00295
00296
00297 domPolylist_Array polylist_arr = mesh->getPolylist_array();
00298 for(size_t itri=0; itri< polylist_arr.getCount(); ++itri)
00299 {
00300 domPolylistRef polylist = polylist_arr.get(itri);
00301
00302 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00303 dae_mesh->mPrimitives.push_back(dae_primitive);
00304 dae_primitive->mType = Dae::PT_POLYGONS;
00305 dae_primitive->mCount = (size_t)polylist->getVcount()->getValue().getCount();
00306
00307
00308 domInputLocalOffset_Array input_arr = polylist->getInput_array();
00309 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00310
00311
00312 size_t ip=0;
00313 for(size_t ivc=0; ivc<polylist->getVcount()->getValue().getCount(); ++ivc)
00314 {
00315 domPRef p = static_cast<domP*>(domP::create(mDAE).cast());
00316 VL_CHECK(p->typeID() == domP::ID());
00317 dae_primitive->mP.push_back( p );
00318 size_t vcount = (size_t)polylist->getVcount()->getValue()[ivc];
00319 p->getValue().setCount(vcount * dae_primitive->mIndexStride);
00320 for(size_t i=0; i<p->getValue().getCount(); ++i)
00321 p->getValue().set(i, polylist->getP()->getValue()[ip++]);
00322 }
00323
00324
00325 dae_primitive->mMaterial = polylist->getMaterial() ? polylist->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00326
00327
00328 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00329 }
00330
00331
00332 domLinestrips_Array linestrip_arr = mesh->getLinestrips_array();
00333 for(size_t itri=0; itri< linestrip_arr.getCount(); ++itri)
00334 {
00335 domLinestripsRef linestrip = linestrip_arr.get(itri);
00336
00337 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00338 dae_mesh->mPrimitives.push_back(dae_primitive);
00339 dae_primitive->mType = Dae::PT_LINE_STRIP;
00340 dae_primitive->mCount = (size_t)linestrip->getCount();
00341
00342
00343 domInputLocalOffset_Array input_arr = linestrip->getInput_array();
00344 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00345
00346
00347 for(size_t ip=0; ip<linestrip->getP_array().getCount(); ++ip)
00348 dae_primitive->mP.push_back( linestrip->getP_array().get(ip) );
00349
00350
00351 dae_primitive->mMaterial = linestrip->getMaterial() ? linestrip->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00352
00353
00354 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00355 }
00356
00357
00358 domLines_Array line_arr = mesh->getLines_array();
00359 for(size_t itri=0; itri< line_arr.getCount(); ++itri)
00360 {
00361 domLinesRef line = line_arr.get(itri);
00362
00363 ref<Dae::Primitive> dae_primitive = new Dae::Primitive;
00364 dae_mesh->mPrimitives.push_back(dae_primitive);
00365 dae_primitive->mType = Dae::PT_LINES;
00366 dae_primitive->mCount = (size_t)line->getCount();
00367
00368
00369 domInputLocalOffset_Array input_arr = line->getInput_array();
00370 parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
00371
00372
00373 dae_primitive->mP.push_back( line->getP() );
00374
00375
00376 dae_primitive->mMaterial = line->getMaterial() ? line->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
00377
00378
00379 generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
00380 }
00381
00382 return dae_mesh;
00383 }
00384
00385 Dae::Source* DaeLoader::getSource(daeElement* source_el)
00386 {
00387 std::map< daeElementRef, ref<Dae::Source> >::iterator it = mSources.find(source_el);
00388 if (it != mSources.end())
00389 return it->second.get();
00390 else
00391 {
00392 VL_CHECK(source_el->typeID() == domSource::ID())
00393 domSourceRef source = static_cast<domSource*>(source_el);
00394
00395 domSource::domTechnique_commonRef tech_common = source->getTechnique_common(); VL_CHECK(tech_common)
00396 domAccessorRef accessor = tech_common->getAccessor();
00397
00398 size_t mask = 0;
00399
00400 domParam_Array param_array = accessor->getParam_array();
00401 size_t attr_count = param_array.getCount() <= 32 ? param_array.getCount() : 32;
00402 for(size_t ipar=0; ipar<attr_count; ++ipar)
00403 {
00404 if (param_array[ipar]->getName() && strlen(param_array[ipar]->getName()))
00405 mask |= 1<<ipar;
00406 }
00407
00408 ref<Dae::Source> dae_source = new Dae::Source;
00409
00410 if (source->getFloat_array())
00411 dae_source->init(source->getFloat_array(), accessor->getCount(), accessor->getStride(), accessor->getOffset(), mask);
00412 else
00413 if (source->getInt_array())
00414 dae_source->init(source->getInt_array(), accessor->getCount(), accessor->getStride(), accessor->getOffset(), mask);
00415 else
00416 if (source->getBool_array())
00417 dae_source->init(source->getBool_array(), accessor->getCount(), accessor->getStride(), accessor->getOffset(), mask);
00418 else
00419 {
00420 Log::error("LoadWriterDae: no supported source data found. Only Float_array, Int_array and Bool_array are supported as source data.\n");
00421 return NULL;
00422 }
00423
00424
00425 mSources[source] = dae_source;
00426
00427 return dae_source.get();
00428 }
00429 }
00430
00431 ref<Effect> DaeLoader::setup_vl_Effect( Dae::Material* mat )
00432 {
00433 VL_CHECK(mat)
00434 VL_CHECK(mat->mDaeEffect)
00435
00436
00437 ref<Effect> fx = new Effect;
00438 fx->shader()->enable(EN_DEPTH_TEST);
00439
00440
00441 if (mat->mDaeEffect->mDaeTechniqueCOMMON)
00442 {
00443 Dae::TechniqueCOMMON* common_tech =mat->mDaeEffect->mDaeTechniqueCOMMON.get();
00444
00445
00446 float transparency = 0;
00447 if ( common_tech->mOpaqueMode == Dae::OM_A_ONE )
00448 transparency = common_tech->mTransparent.mColor.a() * common_tech->mTransparency;
00449 else
00450 transparency = (1.0f - dot( common_tech->mTransparent.mColor.rgb(), fvec3(0.2126f, 0.7152f, 0.0722f))) * common_tech->mTransparency;
00451
00452 bool use_lighting = strstr(mat->mDaeEffect->objectName().c_str(), "blinn:") ||
00453 strstr(mat->mDaeEffect->objectName().c_str(), "phong:") ||
00454 strstr(mat->mDaeEffect->objectName().c_str(), "lambert:");
00455
00456
00457 if ( use_lighting )
00458 {
00459 fx->shader()->enable(EN_LIGHTING);
00460
00461
00462
00463
00464
00465 common_tech->mShininess = vl::clamp(common_tech->mShininess, 0.0f, 128.0f);
00466
00467
00468 fx->shader()->gocMaterial()->setDiffuse ( common_tech->mDiffuse.mColor );
00469 fx->shader()->gocMaterial()->setAmbient ( common_tech->mAmbient.mColor );
00470 fx->shader()->gocMaterial()->setEmission ( common_tech->mEmission.mColor );
00471 fx->shader()->gocMaterial()->setSpecular ( common_tech->mSpecular.mColor );
00472 fx->shader()->gocMaterial()->setShininess( common_tech->mShininess );
00473
00474
00475
00476 if ( common_tech->mDiffuse.mSampler && common_tech->mDiffuse.mSampler->mTexture )
00477 {
00478 fx->shader()->gocTextureSampler(0)->setTexture( common_tech->mDiffuse.mSampler->mTexture.get() );
00479 fx->shader()->gocMaterial()->setDiffuse( vl::white );
00480 }
00481
00482
00483
00484
00485 fx->shader()->gocMaterial()->multiplyTransparency( transparency );
00486 }
00487 else
00488 if ( strstr(mat->mDaeEffect->objectName().c_str(), "constant:") )
00489 {
00490
00491
00492
00493 if ( common_tech->mEmission.mSampler && common_tech->mEmission.mSampler->mTexture )
00494 {
00495 fx->shader()->gocTextureSampler(0)->setTexture( common_tech->mEmission.mSampler->mTexture.get() );
00496
00497 }
00498 else
00499 fx->shader()->gocColor()->setValue( common_tech->mEmission.mColor );
00500 }
00501
00502
00503
00504
00505 if ( transparency < 1.0f || (common_tech->mTransparent.mSampler && common_tech->mTransparent.mSampler == common_tech->mDiffuse.mSampler) )
00506 if (!mAssumeOpaque)
00507 fx->shader()->enable(EN_BLEND);
00508
00509
00510 #if 0
00511 if (!mat->mDaeEffect->mDoubleSided)
00512 fx->shader()->enable(EN_CULL_FACE);
00513 else
00514 if (use_lighting)
00515 fx->shader()->gocLightModel()->setTwoSide(true);
00516 #endif
00517 }
00518 else
00519 {
00520 Log::error("LoadWriterDae: technique or profile not supported.\n");
00521 fx->shader()->gocMaterial()->setDiffuse( vl::fuchsia );
00522 }
00523
00524 return fx;
00525 }
00526
00527 void DaeLoader::bindMaterials(Dae::Node* dae_node, Dae::Mesh* dae_mesh, domBind_materialRef bind_material)
00528 {
00529
00530 std::map< std::string, Dae::Material* > material_map;
00531
00532 if ( bind_material )
00533 {
00534 if (bind_material->getTechnique_common())
00535 {
00536 domInstance_material_Array& material_instances = bind_material->getTechnique_common()->getInstance_material_array();
00537 for(size_t i=0; i<material_instances.getCount(); ++i)
00538 {
00539 daeElement* material = material_instances[i]->getTarget().getElement();
00540 VL_CHECK(material)
00541 std::map< daeElementRef, ref<Dae::Material> >::iterator it = mMaterials.find( material );
00542 if (it != mMaterials.end())
00543 {
00544
00545
00546
00547 material_map[ material_instances[i]->getSymbol() ] = it->second.get();
00548 }
00549 else
00550 {
00551 VL_LOG_DEBUG << "- LoadWriterDae: material '" << material << "' not found!\n";
00552 continue;
00553 }
00554 }
00555 }
00556 else
00557 {
00558 VL_LOG_DEBUG << "- LoadWriterDae: technique_COMMON not found!\n";
00559 }
00560 }
00561
00562
00563 for(size_t iprim=0; iprim<dae_mesh->mPrimitives.size(); ++iprim)
00564 {
00565 ref<Dae::Material> dae_material;
00566
00567 if (!dae_mesh->mPrimitives[iprim]->mMaterial.empty())
00568 {
00569 std::map< std::string, Dae::Material* >::iterator it = material_map.find( dae_mesh->mPrimitives[iprim]->mMaterial );
00570 if (it != material_map.end())
00571 {
00572 dae_material = it->second;
00573 }
00574 else
00575 {
00576 if ( dae_mesh->mPrimitives[iprim]->mMaterial != VL_NO_MATERIAL_SPECIFIED)
00577 {
00578 VL_LOG_DEBUG << "- LoadWriterDae: material symbol " << dae_mesh->mPrimitives[iprim]->mMaterial << " could not be resolved.\n";
00579 }
00580 }
00581 }
00582
00583 ref<Effect> fx = dae_material ? setup_vl_Effect(dae_material.get()) : mDefaultFX;
00584
00585 ref<Actor> actor = new Actor( dae_mesh->mPrimitives[iprim]->mGeometry.get(), fx.get(), dae_node->mTransform.get() );
00586 dae_node->mActors.push_back( actor );
00587 }
00588 }
00589
00590 void DaeLoader::parseNode(daeElement* el, Dae::Node* parent)
00591 {
00592 if (el->typeID() == domNode::ID())
00593 {
00594
00595
00596
00597 ref<Dae::Node> this_node = new Dae::Node;
00598 mNodes.push_back(this_node);
00599 parent->mChildren.push_back( this_node );
00600 parent->mTransform->addChild( this_node->mTransform.get() );
00601
00602 domNode* node = static_cast<domNode*>(el);
00603
00604
00605 domInstance_geometry_Array geometries = node->getInstance_geometry_array();
00606 for(size_t i=0; i<geometries.getCount(); ++i)
00607 {
00608 VL_CHECK(geometries[i]->getUrl().getElement()->typeID() == domGeometry::ID())
00609 daeElement* geometry = geometries[i]->getUrl().getElement();
00610 ref<Dae::Mesh> dae_mesh = parseGeometry(geometry);
00611 if (dae_mesh)
00612 this_node->mMesh.push_back(dae_mesh.get());
00613
00614
00615 bindMaterials(this_node.get(), dae_mesh.get(), geometries[i]->getBind_material());
00616 }
00617
00618
00619 if (loadOptions()->extractSkins())
00620 {
00621 domInstance_controller_Array controllers = node->getInstance_controller_array();
00622 for(size_t i=0; i<controllers.getCount(); ++i)
00623 {
00624 VL_CHECK(controllers[i]->getUrl().getElement()->typeID() == domController::ID())
00625 daeElement* controller_el = controllers[i]->getUrl().getElement();
00626 VL_CHECK(controller_el)
00627 if (!controller_el)
00628 continue;
00629
00630 domController* controller = static_cast<domController*>(controller_el);
00631 daeElement* geometry = controller->getSkin()->getSource().getElement();
00632 VL_CHECK(geometry)
00633 if (!geometry)
00634 continue;
00635
00636 ref<Dae::Mesh> dae_mesh = parseGeometry(geometry);
00637 if (dae_mesh)
00638 this_node->mMesh.push_back(dae_mesh.get());
00639
00640
00641 bindMaterials(this_node.get(), dae_mesh.get(), controllers[i]->getBind_material());
00642 }
00643 }
00644
00645
00646 for(size_t ichild=0; ichild<node->getChildren().getCount(); ++ichild)
00647 {
00648 daeElement* child = node->getChildren()[ichild];
00649
00650 if ( 0 == strcmp(child->getElementName(), "matrix") )
00651 {
00652 domMatrix* matrix = static_cast<domMatrix*>(child);
00653 mat4 local_matrix;
00654 for(int i=0; i<16; ++i)
00655 local_matrix.ptr()[i] = (real)matrix->getValue().get(i);
00656 local_matrix.transpose();
00657 this_node->mTransform->postMultiply(local_matrix);
00658 }
00659 else
00660 if ( 0 == strcmp(child->getElementName(), "translate") )
00661 {
00662 domTranslate* tr = static_cast<domTranslate*>(child);
00663 mat4 m = mat4::getTranslation((real)tr->getValue()[0], (real)tr->getValue()[1], (real)tr->getValue()[2]);
00664 this_node->mTransform->postMultiply( m );
00665 }
00666 else
00667 if ( 0 == strcmp(child->getElementName(), "rotate") )
00668 {
00669 domRotate* rot = static_cast<domRotate*>(child);
00670 mat4 m = mat4::getRotation((real)rot->getValue()[3], (real)rot->getValue()[0], (real)rot->getValue()[1], (real)rot->getValue()[2]);
00671 this_node->mTransform->postMultiply( m );
00672 }
00673 else
00674 if ( 0 == strcmp(child->getElementName(), "scale") )
00675 {
00676 domScale* sc = static_cast<domScale*>(child);
00677 mat4 m = mat4::getScaling((real)sc->getValue()[0], (real)sc->getValue()[1], (real)sc->getValue()[2]);
00678 this_node->mTransform->postMultiply( m );
00679 }
00680 else
00681 if ( 0 == strcmp(child->getElementName(), "lookat") )
00682 {
00683 domLookat* lookat = static_cast<domLookat*>(child);
00684 vec3 eye ((real)lookat->getValue()[0], (real)lookat->getValue()[1], (real)lookat->getValue()[2]);
00685 vec3 look((real)lookat->getValue()[3], (real)lookat->getValue()[4], (real)lookat->getValue()[5]);
00686 vec3 up ((real)lookat->getValue()[6], (real)lookat->getValue()[7], (real)lookat->getValue()[8]);
00687 this_node->mTransform->preMultiply( mat4::getLookAt(eye, look, up) );
00688 }
00689 else
00690 if ( 0 == strcmp(child->getElementName(), "skew") )
00691 {
00692
00693
00694 Log::error("LoadWriterDae: <skew> transform not supported yet. Call me if you know how to compute it.\n");
00695 }
00696 }
00697
00698
00699 domInstance_light_Array lights = node->getInstance_light_array();
00700 for(size_t i=0; i<lights.getCount(); ++i)
00701 {
00702 daeElementRef dae_light = lights[i]->getUrl().getElement();
00703 domLight* dom_light = dynamic_cast<domLight*>(dae_light.cast());
00704 ref<Light> light = parseLight(dom_light, this_node->mTransform.get());
00705 mLights.push_back( light );
00706 }
00707
00708
00709
00710
00711 domInstance_node_Array nodes = node->getInstance_node_array();
00712 for(size_t i=0; i<nodes.getCount(); ++i)
00713 {
00714 daeElement* node = nodes[i]->getUrl().getElement();
00715 VL_CHECK(node->typeID() == domNode::ID())
00716 parseNode(node, this_node.get());
00717 }
00718
00719
00720 daeTArray< daeSmartRef<daeElement> > children = node->getChildren();
00721 for(size_t i=0; i<children.getCount(); ++i)
00722 parseNode(children[i], this_node.get());
00723 }
00724 }
00725
00726 bool DaeLoader::load(VirtualFile* file)
00727 {
00728 reset();
00729
00730 mFilePath = file->path();
00731
00732
00733 std::vector<char> buffer;
00734 file->load(buffer);
00735 if (buffer.empty())
00736 return false;
00737 buffer.push_back(0);
00738
00739 daeElement* root = mDAE.openFromMemory(file->path().toStdString(), (char*)&buffer[0]);
00740 if (!root)
00741 {
00742 Log::error( "LoadWriterDae: failed to open COLLADA document.\n" );
00743 return false;
00744 }
00745
00746 parseAsset(root);
00747
00748 parseImages(root->getDescendant("library_images"));
00749
00750 parseEffects(root->getDescendant("library_effects"));
00751
00752 parseMaterials(root->getDescendant("library_materials"));
00753
00754 daeElement* visual_scene = root->getDescendant("visual_scene");
00755 if (!visual_scene)
00756 {
00757 Log::error( "LoadWriterDae: <visual_scene> not found!\n" );
00758 return false;
00759 }
00760
00761
00762
00763 mScene = new Dae::Node;
00764 daeTArray< daeSmartRef<daeElement> > children = visual_scene->getChildren();
00765 for(size_t i=0; i<children.getCount(); ++i)
00766 parseNode(children[i], mScene.get());
00767
00768
00769
00770
00771
00772
00773
00774
00775 mScene->mTransform->preMultiply( mUpMatrix );
00776
00777 mScene->mTransform->computeWorldMatrixRecursive();
00778
00779
00780
00781
00782 setupLights();
00783
00784
00785 for( size_t inode=0; inode<mNodes.size(); ++inode )
00786 {
00787 for(size_t i=0; i<mNodes[inode]->mActors.size(); ++i)
00788 {
00789 Actor* actor = mNodes[inode]->mActors[i].get();
00790
00791
00792 mResources->resources().push_back( actor );
00793
00794
00795 if ( loadOptions()->flattenTransformHierarchy() )
00796 actor->transform()->removeFromParent();
00797
00798
00799 if (loadOptions()->mergeDrawCalls())
00800 {
00801 Geometry* geom = actor->lod(0)->as<Geometry>();
00802 if (geom)
00803 {
00804
00805 ref<DrawCall> tristrips = geom->mergeTriangleStrips();
00806
00807 geom->drawCalls()->erase( tristrips.get() );
00808
00809
00810 geom->mergeDrawCallsWithTriangles(PT_UNKNOWN);
00811
00812
00813 if (tristrips.get())
00814 geom->drawCalls()->push_back( tristrips.get() );
00815 }
00816 }
00817
00818
00819 mat4 nmatrix = actor->transform()->worldMatrix().as3x3().invert().transpose();
00820 real len_x = nmatrix.getX().length();
00821 real len_y = nmatrix.getY().length();
00822 real len_z = nmatrix.getZ().length();
00823 if ( fabs(len_x - 1) > 0.05f || fabs(len_y - 1) > 0.05f || fabs(len_z - 1) > 0.05f )
00824 {
00825
00826 if ( actor->effect()->shader()->isEnabled(vl::EN_LIGHTING) )
00827 actor->effect()->shader()->enable(vl::EN_NORMALIZE);
00828 }
00829
00830
00831 if ( actor->effect()->shader()->isEnabled(EN_LIGHTING) )
00832 {
00833
00834
00835 ref<Effect> fx = new Effect;
00836 fx->setObjectName( actor->effect()->objectName().c_str() );
00837 fx->shader()->setEnableSet( actor->effect()->shader()->getEnableSet() );
00838 fx->shader()->setRenderStateSet( actor->effect()->shader()->getRenderStateSet() );
00839 actor->setEffect( fx.get() );
00840 for(size_t ilight=0; ilight<mLights.size() && ilight<8; ++ilight)
00841 fx->shader()->setRenderState( mLights[ilight].get(), ilight );
00842
00843
00844 Geometry* geom = actor->lod(0)->as<Geometry>();
00845 if ( loadOptions()->computeMissingNormals() && geom && !geom->normalArray() )
00846 geom->computeNormals();
00847 }
00848 }
00849 }
00850
00851 if ( loadOptions()->flattenTransformHierarchy() )
00852 mScene->mTransform->flattenHierarchy();
00853 else
00854 mResources->resources().push_back( mScene->mTransform );
00855
00856 return true;
00857 }
00858
00859 std::string DaeLoader::percentDecode(const char* uri)
00860 {
00861 std::string str;
00862 for(int i=0; uri[i]; ++i)
00863 {
00864
00865 if ( uri[i] == '%' && uri[i+1] && uri[i+2] )
00866 {
00867 ++i;
00868 char hex1 = uri[i];
00869 if (hex1 >= '0' && hex1 <= '9')
00870 hex1 -= '0';
00871 else
00872 if (hex1 >= 'A' && hex1 <= 'F')
00873 hex1 -= 'A';
00874 else
00875 if (hex1 >= 'a' && hex1 <= 'f')
00876 hex1 -= 'a';
00877 else
00878 hex1 = -1;
00879
00880 ++i;
00881 char hex2 = uri[i];
00882 if (hex2 >= '0' && hex2 <= '9')
00883 hex2 -= '0';
00884 else
00885 if (hex2 >= 'A' && hex2 <= 'F')
00886 hex2 -= 'A';
00887 else
00888 if (hex2 >= 'a' && hex2 <= 'f')
00889 hex2 -= 'a';
00890 else
00891 hex2 = -1;
00892
00893
00894 if (hex1 == -1 || hex2 == -1)
00895 {
00896
00897 str.push_back('%');
00898 i -= 2;
00899 }
00900
00901 char ch = (hex1 << 4) + (hex2);
00902 str.push_back(ch);
00903 }
00904 else
00905 str.push_back(uri[i]);
00906 }
00907 return str;
00908 }
00909
00910 void DaeLoader::loadImages(const domImage_Array& images)
00911 {
00912 for(size_t i=0; i<images.getCount(); ++i)
00913 {
00914 if ( strstr( images[i]->getInit_from()->getValue().getProtocol(), "file") == 0 )
00915 {
00916 Log::error( Say("LoadWriterDae: protocol not supported: %s\n") << images[i]->getInit_from()->getValue().getURI() );
00917 continue;
00918 }
00919
00920 std::string full_path = percentDecode( images[i]->getInit_from()->getValue().getURI() + 6 );
00921 ref<Image> image = loadImage( full_path.c_str() );
00922
00923 mImages[ images[i].cast() ] = image;
00924 }
00925 }
00926
00927 void DaeLoader::parseImages(daeElement* library)
00928 {
00929 if (!library)
00930 return;
00931 domLibrary_images* library_images = static_cast<domLibrary_images*>(library);
00932 const domImage_Array& images = library_images->getImage_array();
00933 loadImages(images);
00934 }
00935
00936 void DaeLoader::parseEffects(daeElement* library)
00937 {
00938 if (!library)
00939 return;
00940 domLibrary_effects* library_effects = static_cast<domLibrary_effects*>(library);
00941 const domEffect_Array& effects = library_effects->getEffect_array();
00942 for(size_t i=0; i<effects.getCount(); ++i)
00943 {
00944 domEffect* effect = effects[i].cast();
00945
00946 ref<Dae::Effect> dae_effect = new Dae::Effect;
00947
00948 std::string effect_name;
00949 if (effect->getName())
00950 effect_name = effect->getName();
00951
00952 mEffects[effect] = dae_effect;
00953
00954
00955 loadImages(effect->getImage_array());
00956
00957 const domFx_profile_abstract_Array& profiles = effect->getFx_profile_abstract_array();
00958 for(size_t i=0; i<profiles.getCount(); ++i)
00959 {
00960
00961 if ( profiles[i]->typeID() == domProfile_COMMON::ID() )
00962 {
00963 domProfile_COMMON* common = static_cast<domProfile_COMMON*>(profiles[i].cast());
00964
00965
00966 for(size_t ipar=0; ipar<common->getNewparam_array().getCount(); ++ipar)
00967 {
00968 domCommon_newparam_typeRef newparam = common->getNewparam_array()[ipar];
00969
00970 ref<Dae::NewParam> dae_newparam = new Dae::NewParam;
00971 dae_effect->mNewParams.push_back( dae_newparam );
00972
00973
00974 mDaeNewParams[newparam.cast()] = dae_newparam;
00975
00976
00977
00978 if (newparam->getSurface())
00979 {
00980 domFx_surface_commonRef surface = newparam->getSurface();
00981
00982 if ( !surface->getFx_surface_init_common()->getInit_from_array().getCount() )
00983 {
00984 VL_LOG_DEBUG << "- 'surface->getFx_surface_init_common()->getInit_from_array().getCount()' is 0: " << __FILE__ << ":" << __LINE__ << "\n";
00985 continue;
00986 }
00987
00988 dae_newparam->mDaeSurface = new Dae::Surface;
00989 daeElement* ref_image = surface->getFx_surface_init_common()->getInit_from_array()[0]->getValue().getElement();
00990 if (!ref_image)
00991 {
00992 VL_LOG_DEBUG << "- 'surface->getFx_surface_init_common()->getInit_from_array()[0]->getValue().getElement()' FAILED: " << __FILE__ << ":" << __LINE__ << "\n";
00993 continue;
00994 }
00995
00996 std::map< daeElementRef, ref<Image> >::iterator it = mImages.find( ref_image );
00997 if (it != mImages.end())
00998 dae_newparam->mDaeSurface->mImage = it->second.get();
00999 else
01000 {
01001 VL_LOG_DEBUG << "- 'mImages.find( ref_image )' FAILED: " << __FILE__ << ":" << __LINE__ << "\n";
01002 continue;
01003 }
01004 }
01005
01006
01007 if (newparam->getSampler2D())
01008 {
01009 domFx_sampler2D_commonRef sampler2D = newparam->getSampler2D();
01010
01011 dae_newparam->mDaeSampler2D = new Dae::Sampler2D;
01012
01013
01014 daeSIDResolver sid_res( effect, sampler2D->getSource()->getValue() );
01015 domElement* surface_newparam = sid_res.getElement();
01016 if(!surface_newparam)
01017 {
01018 VL_LOG_DEBUG << (Say("- <surface> '%s' referenced by <sampler2D> '%s' not found!\n") << sampler2D->getSource()->getValue() << newparam->getSid() );
01019 continue;
01020 }
01021
01022 std::map< daeElementRef, ref<Dae::NewParam> >::iterator it = mDaeNewParams.find(surface_newparam);
01023 if ( it != mDaeNewParams.end() )
01024 {
01025 dae_newparam->mDaeSampler2D->mDaeSurface = it->second->mDaeSurface;
01026 }
01027 else
01028 {
01029 VL_LOG_DEBUG << "- 'mDaeNewParams.find(surface_newparam)' FAILED: " << __FILE__ << ":" << __LINE__ << "\n";
01030 continue;
01031 }
01032
01033
01034 if( sampler2D->getMinfilter() )
01035 {
01036 dae_newparam->mDaeSampler2D->mMinFilter = translateSampleFilter( sampler2D->getMinfilter()->getValue() );
01037 }
01038
01039
01040
01041 if( sampler2D->getMagfilter() )
01042 {
01043 dae_newparam->mDaeSampler2D->mMagFilter = translateSampleFilter( sampler2D->getMagfilter()->getValue() );
01044 }
01045
01046
01047 if (sampler2D->getWrap_s())
01048 {
01049 dae_newparam->mDaeSampler2D->mWrapS = translateWrapMode( sampler2D->getWrap_s()->getValue() );
01050 }
01051
01052
01053 if (sampler2D->getWrap_t())
01054 {
01055 dae_newparam->mDaeSampler2D->mWrapT = translateWrapMode( sampler2D->getWrap_t()->getValue() );
01056 }
01057
01058
01059 prepareTexture2D(dae_newparam->mDaeSampler2D.get());
01060 }
01061
01062
01063 if ( newparam->getFloat() )
01064 {
01065 dae_newparam->mFloat4 = fvec4((float)newparam->getFloat()->getValue(), 0, 0, 0);
01066 }
01067 else
01068 if ( newparam->getFloat2() )
01069 {
01070 daeDouble* fptr = &newparam->getFloat2()->getValue()[0];
01071 dae_newparam->mFloat4 = fvec4((float)fptr[0], (float)fptr[1], 0, 0);
01072 }
01073 else
01074 if ( newparam->getFloat3() )
01075 {
01076 daeDouble* fptr = &newparam->getFloat3()->getValue()[0];
01077 dae_newparam->mFloat4 = fvec4((float)fptr[0], (float)fptr[1], (float)fptr[2], 0);
01078 }
01079 else
01080 if ( newparam->getFloat4() )
01081 {
01082 daeDouble* fptr = &newparam->getFloat4()->getValue()[0];
01083 dae_newparam->mFloat4 = fvec4((float)fptr[0], (float)fptr[1], (float)fptr[2], (float)fptr[3]);
01084 }
01085 }
01086
01087
01088
01089
01090 if (common->getTechnique()->getBlinn())
01091 {
01092
01093 effect_name = "blinn:"+effect_name;
01094
01095 domProfile_COMMON::domTechnique::domBlinnRef blinn = common->getTechnique()->getBlinn();
01096
01097 dae_effect->mDaeTechniqueCOMMON = new Dae::TechniqueCOMMON;
01098 parseColor( common, blinn->getEmission(), &dae_effect->mDaeTechniqueCOMMON->mEmission );
01099 parseColor( common, blinn->getAmbient(), &dae_effect->mDaeTechniqueCOMMON->mAmbient );
01100 parseColor( common, blinn->getDiffuse(), &dae_effect->mDaeTechniqueCOMMON->mDiffuse );
01101 parseColor( common, blinn->getSpecular(), &dae_effect->mDaeTechniqueCOMMON->mSpecular );
01102 if (blinn->getShininess())
01103 dae_effect->mDaeTechniqueCOMMON->mShininess = (float)blinn->getShininess()->getFloat()->getValue();
01104
01105 parseColor( common, blinn->getReflective(), &dae_effect->mDaeTechniqueCOMMON->mReflective );
01106 if (blinn->getReflectivity())
01107 dae_effect->mDaeTechniqueCOMMON->mReflectivity = (float)blinn->getReflectivity()->getFloat()->getValue();
01108
01109 if (blinn->getTransparent())
01110 {
01111 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01112 parseColor( common, blinn->getTransparent(), &dae_effect->mDaeTechniqueCOMMON->mTransparent );
01113 dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = blinn->getTransparent()->getOpaque() == FX_OPAQUE_ENUM_A_ONE ? Dae::OM_A_ONE : Dae::OM_RGB_ZERO;
01114 }
01115 if (blinn->getTransparency())
01116 {
01117 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01118 dae_effect->mDaeTechniqueCOMMON->mTransparency = (float)blinn->getTransparency()->getFloat()->getValue();
01119 }
01120 }
01121 else
01122 if (common->getTechnique()->getPhong())
01123 {
01124
01125 effect_name = "phong:"+effect_name;
01126
01127 domProfile_COMMON::domTechnique::domPhongRef phong = common->getTechnique()->getPhong();
01128
01129 dae_effect->mDaeTechniqueCOMMON = new Dae::TechniqueCOMMON;
01130 parseColor( common, phong->getEmission(), &dae_effect->mDaeTechniqueCOMMON->mEmission );
01131 parseColor( common, phong->getAmbient(), &dae_effect->mDaeTechniqueCOMMON->mAmbient );
01132 parseColor( common, phong->getDiffuse(), &dae_effect->mDaeTechniqueCOMMON->mDiffuse );
01133 parseColor( common, phong->getSpecular(), &dae_effect->mDaeTechniqueCOMMON->mSpecular );
01134 if (phong->getShininess())
01135 {
01136 dae_effect->mDaeTechniqueCOMMON->mShininess = (float)phong->getShininess()->getFloat()->getValue();
01137 }
01138
01139 parseColor( common, phong->getReflective(), &dae_effect->mDaeTechniqueCOMMON->mReflective );
01140 if (phong->getReflectivity())
01141 dae_effect->mDaeTechniqueCOMMON->mReflectivity = (float)phong->getReflectivity()->getFloat()->getValue();
01142
01143 if (phong->getTransparent())
01144 {
01145 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01146 parseColor( common, phong->getTransparent(), &dae_effect->mDaeTechniqueCOMMON->mTransparent );
01147 dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = phong->getTransparent()->getOpaque() == FX_OPAQUE_ENUM_A_ONE ? Dae::OM_A_ONE : Dae::OM_RGB_ZERO;
01148 }
01149 if (phong->getTransparency())
01150 {
01151 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01152 dae_effect->mDaeTechniqueCOMMON->mTransparency = (float)phong->getTransparency()->getFloat()->getValue();
01153 }
01154 }
01155 else
01156 if (common->getTechnique()->getLambert())
01157 {
01158
01159 effect_name = "lambert:"+effect_name;
01160
01161 domProfile_COMMON::domTechnique::domLambertRef lambert = common->getTechnique()->getLambert();
01162
01163 dae_effect->mDaeTechniqueCOMMON = new Dae::TechniqueCOMMON;
01164 parseColor( common, lambert->getEmission(), &dae_effect->mDaeTechniqueCOMMON->mEmission );
01165 parseColor( common, lambert->getAmbient(), &dae_effect->mDaeTechniqueCOMMON->mAmbient );
01166 parseColor( common, lambert->getDiffuse(), &dae_effect->mDaeTechniqueCOMMON->mDiffuse );
01167 dae_effect->mDaeTechniqueCOMMON->mSpecular.mColor = fvec4(0,0,0,1);
01168 dae_effect->mDaeTechniqueCOMMON->mShininess = 0;
01169
01170 parseColor( common, lambert->getReflective(), &dae_effect->mDaeTechniqueCOMMON->mReflective );
01171 if (lambert->getReflectivity())
01172 dae_effect->mDaeTechniqueCOMMON->mReflectivity = (float)lambert->getReflectivity()->getFloat()->getValue();
01173
01174 if (lambert->getTransparent())
01175 {
01176 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01177 parseColor( common, lambert->getTransparent(), &dae_effect->mDaeTechniqueCOMMON->mTransparent );
01178 dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = lambert->getTransparent()->getOpaque() == FX_OPAQUE_ENUM_A_ONE ? Dae::OM_A_ONE : Dae::OM_RGB_ZERO;
01179 }
01180 if (lambert->getTransparency())
01181 {
01182 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01183 dae_effect->mDaeTechniqueCOMMON->mTransparency = (float)lambert->getTransparency()->getFloat()->getValue();
01184 }
01185 }
01186 else
01187 if (common->getTechnique()->getConstant())
01188 {
01189
01190 effect_name = "constant:"+effect_name;
01191
01192 domProfile_COMMON::domTechnique::domConstantRef constant = common->getTechnique()->getConstant();
01193
01194 dae_effect->mDaeTechniqueCOMMON = new Dae::TechniqueCOMMON;
01195 parseColor( common, constant->getEmission(), &dae_effect->mDaeTechniqueCOMMON->mEmission );
01196 dae_effect->mDaeTechniqueCOMMON->mAmbient.mColor = fvec4(0,0,0,1);
01197 dae_effect->mDaeTechniqueCOMMON->mDiffuse.mColor = fvec4(0,0,0,1);
01198 dae_effect->mDaeTechniqueCOMMON->mSpecular.mColor = fvec4(0,0,0,1);
01199 dae_effect->mDaeTechniqueCOMMON->mShininess = 0;
01200
01201 parseColor( common, constant->getReflective(), &dae_effect->mDaeTechniqueCOMMON->mReflective );
01202 if (constant->getReflectivity())
01203 dae_effect->mDaeTechniqueCOMMON->mReflectivity = (float)constant->getReflectivity()->getFloat()->getValue();
01204
01205 if (constant->getTransparent())
01206 {
01207 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01208 parseColor( common, constant->getTransparent(), &dae_effect->mDaeTechniqueCOMMON->mTransparent );
01209 dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = constant->getTransparent()->getOpaque() == FX_OPAQUE_ENUM_A_ONE ? Dae::OM_A_ONE : Dae::OM_RGB_ZERO;
01210 }
01211 if (constant->getTransparency())
01212 {
01213 dae_effect->mDaeTechniqueCOMMON->mBlendingOn = true;
01214 dae_effect->mDaeTechniqueCOMMON->mTransparency = (float)constant->getTransparency()->getFloat()->getValue();
01215 }
01216 }
01217 else
01218 {
01219 Log::error("LoadWriterDae: technique not supported.\n");
01220 }
01221
01222 dae_effect->setObjectName( effect_name.c_str() );
01223
01224
01225 if (mAssumeOpaque)
01226 {
01227 dae_effect->mDaeTechniqueCOMMON->mTransparency = 1.0f;
01228 dae_effect->mDaeTechniqueCOMMON->mTransparent.mColor = fvec4(0, 0, 0, 1);
01229 dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = Dae::OM_A_ONE;
01230 }
01231 else
01232 if(mInvertTransparency)
01233 {
01234 dae_effect->mDaeTechniqueCOMMON->mTransparency = 1.0f - dae_effect->mDaeTechniqueCOMMON->mTransparency;
01235
01236 dae_effect->mDaeTechniqueCOMMON->mTransparent.mColor = fvec4(0, 0, 0, 1);
01237 dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = Dae::OM_A_ONE;
01238 }
01239
01240
01241
01242 for(size_t iextra=0; iextra<common->getExtra_array().getCount(); ++iextra)
01243 {
01244 domExtraRef extra = common->getExtra_array()[iextra];
01245 for(size_t itech=0; itech<extra->getTechnique_array().getCount(); ++itech)
01246 {
01247 domTechniqueRef tech = extra->getTechnique_array()[itech];
01248 if ( strstr(tech->getProfile(), "GOOGLEEARTH") )
01249 {
01250 domAny* double_sided = (domAny*)tech->getChild("double_sided");
01251 if (double_sided)
01252 {
01253 const char* ptr = double_sided->getValue();
01254 if(strcmp(ptr, "1") == 0)
01255 dae_effect->mDoubleSided = true;
01256 }
01257 }
01258 }
01259 }
01260
01261 }
01262
01263 }
01264 }
01265 }
01266
01267 void DaeLoader::prepareTexture2D(Dae::Sampler2D* sampler2D)
01268 {
01269 if (sampler2D->mDaeSurface && sampler2D->mDaeSurface->mImage)
01270 {
01271 bool use_mipmaps = true;
01272 switch(sampler2D->mMinFilter)
01273 {
01274 case TPF_LINEAR:
01275 case TPF_NEAREST:
01276 if ( loadOptions()->useAlwaysMipmapping() )
01277 sampler2D->mMinFilter = TPF_LINEAR_MIPMAP_NEAREST;
01278 else
01279 use_mipmaps = false;
01280 default:
01281 break;
01282 }
01283
01284 sampler2D->mTexture = new Texture;
01285 sampler2D->mTexture->prepareTexture2D(sampler2D->mDaeSurface->mImage.get(), TF_UNKNOWN, use_mipmaps, false);
01286 sampler2D->mTexture->getTexParameter()->setWrapS(sampler2D->mWrapS);
01287 sampler2D->mTexture->getTexParameter()->setWrapT(sampler2D->mWrapT);
01288 sampler2D->mTexture->getTexParameter()->setMinFilter(sampler2D->mMinFilter);
01289 sampler2D->mTexture->getTexParameter()->setMagFilter(sampler2D->mMagFilter);
01290 }
01291 }
01292
01293 void DaeLoader::parseMaterials(daeElement* library)
01294 {
01295 if (!library)
01296 return;
01297 domLibrary_materials* library_materials = static_cast<domLibrary_materials*>(library);
01298 const domMaterial_Array& materials = library_materials->getMaterial_array();
01299 for(size_t i=0; i<materials.getCount(); ++i)
01300 {
01301 domElement* effect = materials[i]->getInstance_effect()->getUrl().getElement();
01302 if (!effect)
01303 {
01304 VL_LOG_DEBUG << "- 'materials[i]->getInstance_effect()->getUrl().getElement()' FAILED: " << __FILE__ << ":" << __LINE__ << "\n";
01305 continue;
01306 }
01307
01308 std::map< daeElementRef, ref<Dae::Effect> >::iterator it = mEffects.find(effect);
01309 if (it != mEffects.end())
01310 {
01311 domMaterial* material = materials[i].cast();
01312 ref<Dae::Material> dae_material = new Dae::Material;
01313 dae_material->mDaeEffect = it->second;
01314 mMaterials[ material ] = dae_material;
01315 }
01316 else
01317 {
01318 VL_LOG_DEBUG << "- 'mEffects.find(effect)' FAILED: " << __FILE__ << ":" << __LINE__ << "\n";
01319 continue;
01320 }
01321 }
01322 }
01323
01324 ref<Light> DaeLoader::parseLight(domLight* dom_light, Transform* transform)
01325 {
01326 domLight::domTechnique_commonRef light_common = dom_light->getTechnique_common();
01327
01328 ref<Light> light = new Light;
01329 if (dom_light->getName())
01330 light->setObjectName( dom_light->getName() );
01331 else
01332 if (dom_light->getID())
01333 light->setObjectName( dom_light->getID() );
01334
01335 light->bindTransform(transform);
01336
01337 if (light_common->getPoint())
01338 {
01339 domLight::domTechnique_common::domPointRef point = light_common->getPoint();
01340
01341 if (point->getColor())
01342 {
01343 domFloat3& c = point->getColor()->getValue();
01344 fvec4 color((float)c[0], (float)c[1], (float)c[2], 1);
01345 light->setAmbient( fvec4(0,0,0,1) );
01346 light->setDiffuse(color);
01347 light->setSpecular(color);
01348 }
01349
01350 if (point->getConstant_attenuation())
01351 light->setConstantAttenuation( (float)point->getConstant_attenuation()->getValue() );
01352 if (point->getLinear_attenuation())
01353 light->setLinearAttenuation( (float)point->getLinear_attenuation()->getValue() );
01354 if (point->getQuadratic_attenuation())
01355 light->setQuadraticAttenuation( (float)point->getQuadratic_attenuation()->getValue() );
01356
01357 light->setPosition( fvec4(0,0,0,1) );
01358 }
01359 else
01360 if (light_common->getDirectional())
01361 {
01362 domLight::domTechnique_common::domDirectionalRef directional = light_common->getDirectional();
01363
01364 if (directional->getColor())
01365 {
01366 domFloat3& c = directional->getColor()->getValue();
01367 fvec4 color((float)c[0], (float)c[1], (float)c[2], 1);
01368 light->setAmbient( fvec4(0,0,0,1) );
01369 light->setDiffuse(color);
01370 light->setSpecular(color);
01371 }
01372
01373 light->setPosition( fvec4( 0, 0, 1, 0) );
01374 }
01375 else
01376 if (light_common->getSpot())
01377 {
01378 domLight::domTechnique_common::domSpotRef spot= light_common->getSpot();
01379
01380 if (spot->getColor())
01381 {
01382 domFloat3& c = spot->getColor()->getValue();
01383 fvec4 color((float)c[0], (float)c[1], (float)c[2], 1);
01384 light->setAmbient( fvec4(0,0,0,1) );
01385 light->setDiffuse(color);
01386 light->setSpecular(color);
01387 }
01388
01389 if (spot->getConstant_attenuation())
01390 light->setConstantAttenuation( (float)spot->getConstant_attenuation()->getValue() );
01391 if (spot->getLinear_attenuation())
01392 light->setLinearAttenuation( (float)spot->getLinear_attenuation()->getValue() );
01393 if (spot->getQuadratic_attenuation())
01394 light->setQuadraticAttenuation( (float)spot->getQuadratic_attenuation()->getValue() );
01395
01396 if (spot->getFalloff_angle())
01397 light->setSpotCutoff( (float)spot->getFalloff_angle()->getValue() );
01398 if (spot->getFalloff_exponent())
01399 light->setSpotExponent( (float)spot->getFalloff_exponent()->getValue() );
01400
01401 light->setSpotDirection( fvec3(0,0,-1) );
01402 light->setPosition( fvec4( 0, 0, 0, 1) );
01403 }
01404 else
01405 if (light_common->getAmbient())
01406 {
01407 domLight::domTechnique_common::domAmbientRef ambient = light_common->getAmbient();
01408
01409 if (ambient->getColor())
01410 {
01411 domFloat3& c = ambient->getColor()->getValue();
01412 fvec4 color((float)c[0], (float)c[1], (float)c[2], 1);
01413 light->setAmbient( color );
01414 light->setDiffuse( fvec4(0,0,0,1) );
01415 light->setSpecular( fvec4(0,0,0,1) );
01416 }
01417
01418
01419 light->setPosition( fvec4( 0, 0, 0, 1) );
01420
01421
01422 light->setConstantAttenuation( 1 );
01423 light->setLinearAttenuation( 0 );
01424 light->setQuadraticAttenuation( 0 );
01425 }
01426
01427 return light;
01428 }
01429
01430 void DaeLoader::setupLights()
01431 {
01432
01433 if (loadOptions()->lightMeshSize())
01434 {
01435 for(size_t i=0; i<mLights.size(); ++i)
01436 {
01437
01438 if (mLights[i]->spotCutoff() != 180)
01439 {
01440 ref<Geometry> light_mesh = vl::makeCone( vec3(0,0,0), loadOptions()->lightMeshSize(), loadOptions()->lightMeshSize(), 10 );
01441 light_mesh->transform( mat4::getTranslation(0,loadOptions()->lightMeshSize(),0) );
01442 light_mesh->transform( mat4::getRotation(90, +1,0,0) );
01443 light_mesh->setObjectName( ("LightMesh-" + mLights[i]->objectName()).c_str() );
01444 ref<Effect> fx = new Effect;
01445 fx->shader()->enable(EN_DEPTH_TEST);
01446 fx->shader()->gocPolygonMode()->set(PM_LINE, PM_LINE);
01447 fx->shader()->gocColor()->setValue(vl::fuchsia);
01448 mResources->resources().push_back( new Actor( light_mesh.get(), fx.get(), mLights[i]->boundTransform() ) );
01449 }
01450 else
01451
01452 if (mLights[i]->position().w() == 0)
01453 {
01454 ref<Geometry> light_mesh = vl::makePyramid( vec3(0,0,0), loadOptions()->lightMeshSize() / 2, loadOptions()->lightMeshSize() );
01455 light_mesh->transform( mat4::getRotation(90, -1,0,0) );
01456 light_mesh->setObjectName( ("LightMesh-" + mLights[i]->objectName()).c_str() );
01457 ref<Effect> fx = new Effect;
01458 fx->shader()->enable(EN_DEPTH_TEST);
01459 fx->shader()->gocPolygonMode()->set(PM_LINE, PM_LINE);
01460 fx->shader()->gocColor()->setValue(vl::fuchsia);
01461 mResources->resources().push_back( new Actor( light_mesh.get(), fx.get(), mLights[i]->boundTransform() ) );
01462 }
01463 else
01464
01465 if( mLights[i]->ambient() == fvec4(0,0,0,1) )
01466 {
01467 ref<Geometry> light_mesh = vl::makeUVSphere( vec3(0,0,0), loadOptions()->lightMeshSize(), 10, 5);
01468 light_mesh->setObjectName( ("LightMesh-" + mLights[i]->objectName()).c_str() );
01469 ref<Effect> fx = new Effect;
01470 fx->shader()->enable(EN_DEPTH_TEST);
01471 fx->shader()->gocPolygonMode()->set(PM_LINE, PM_LINE);
01472 fx->shader()->gocColor()->setValue(vl::fuchsia);
01473 mResources->resources().push_back( new Actor( light_mesh.get(), fx.get(), mLights[i]->boundTransform() ) );
01474 }
01475 else
01476
01477 {
01478 ref<Geometry> light_mesh = vl::makeTorus( vec3(0,0,0), loadOptions()->lightMeshSize(), loadOptions()->lightMeshSize()/4, 8, 14);
01479 light_mesh->setNormalArray(NULL);
01480 light_mesh->setObjectName( ("LightMesh-" + mLights[i]->objectName()).c_str() );
01481 ref<Effect> fx = new Effect;
01482 fx->shader()->enable(EN_DEPTH_TEST);
01483 fx->shader()->gocPolygonMode()->set(PM_LINE, PM_LINE);
01484 fx->shader()->gocColor()->setValue(vl::fuchsia);
01485 mResources->resources().push_back( new Actor( light_mesh.get(), fx.get(), mLights[i]->boundTransform() ) );
01486 }
01487 }
01488 }
01489
01490 struct dummy
01491 {
01492 static bool light_sorter(const ref<Light>& a, const ref<Light>& b)
01493 {
01494
01495 if (a->ambient() != b->ambient())
01496 return b->ambient() < a->ambient();
01497 else
01498
01499 if (a->position().w() != b->position().w())
01500 return a->position().w() < b->position().w();
01501 else
01502
01503 return a->spotCutoff() > b->spotCutoff();
01504 }
01505 };
01506
01507 std::sort(mLights.begin(), mLights.end(), dummy::light_sorter);
01508
01509
01510 for(size_t i=0; i<mLights.size(); ++i)
01511 {
01512 mResources->resources().push_back( mLights[i].get() );
01513 }
01514
01515 if (loadOptions()->exportLights() == false)
01516 mLights.clear();
01517
01518
01519 if (mLights.empty())
01520 {
01521 mLights.push_back( new Light );
01522 mLights[0]->setObjectName(VL_DEFAULT_LIGHT);
01523 }
01524 }
01525
01526 Dae::EInputSemantic DaeLoader::getSemantic(const char* semantic)
01527 {
01528 for(int i=0; SemanticTable[i].mSemanticString; ++i)
01529 {
01530 if (strcmp(semantic, SemanticTable[i].mSemanticString) == 0)
01531 return SemanticTable[i].mSemantic;
01532 }
01533
01534 return Dae::IS_UNKNOWN;
01535 }
01536
01537 const char* DaeLoader::getSemanticString(Dae::EInputSemantic semantic)
01538 {
01539 for(int i=0; SemanticTable[i].mSemanticString; ++i)
01540 {
01541 if ( semantic == SemanticTable[i].mSemantic )
01542 return SemanticTable[i].mSemanticString;
01543 }
01544
01545 return NULL;
01546 }
01547
01548 ETexParamFilter DaeLoader::translateSampleFilter(domFx_sampler_filter_common filter)
01549 {
01550 switch(filter)
01551 {
01552 case FX_SAMPLER_FILTER_COMMON_NEAREST: return TPF_NEAREST;
01553 case FX_SAMPLER_FILTER_COMMON_LINEAR: return TPF_LINEAR;
01554 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: return TPF_NEAREST_MIPMAP_NEAREST;
01555 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: return TPF_LINEAR_MIPMAP_NEAREST;
01556 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: return TPF_NEAREST_MIPMAP_LINEAR;
01557 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: return TPF_LINEAR_MIPMAP_LINEAR;
01558 default: return (ETexParamFilter)0;
01559 }
01560 }
01561
01562 ETexParamWrap DaeLoader::translateWrapMode(domFx_sampler_wrap_common wrap)
01563 {
01564 switch(wrap)
01565 {
01566 case FX_SAMPLER_WRAP_COMMON_WRAP: return TPW_REPEAT;
01567 case FX_SAMPLER_WRAP_COMMON_MIRROR: return TPW_MIRRORED_REPEAT;
01568 case FX_SAMPLER_WRAP_COMMON_CLAMP: return TPW_CLAMP;
01569 case FX_SAMPLER_WRAP_COMMON_BORDER: return TPW_CLAMP_TO_BORDER;
01570 default: return (ETexParamWrap)0;
01571 }
01572 }
01573
01574 template<class T_color_or_texture>
01575 void DaeLoader::parseColor(const domProfile_COMMON* common, const T_color_or_texture& color_or_texture, Dae::ColorOrTexture* out_col)
01576 {
01577 if (!color_or_texture)
01578 return;
01579
01580 if (color_or_texture->getColor())
01581 {
01582 domFx_color_common& col = color_or_texture->getColor()->getValue();
01583 out_col->mColor = fvec4( (float)col[0], (float)col[1], (float)col[2], (float)col[3] );
01584 }
01585
01586 if (color_or_texture->getTexture())
01587 {
01588
01589 daeSIDResolver sid_res( const_cast<domProfile_COMMON*>(common), color_or_texture->getTexture()->getTexture() );
01590 domElement* sampler2D_newparam = sid_res.getElement();
01591
01592 std::map< daeElementRef, ref<Dae::NewParam> >::iterator it = mDaeNewParams.find(sampler2D_newparam);
01593 if ( it != mDaeNewParams.end() )
01594 {
01595 VL_CHECK(it->second->mDaeSampler2D)
01596 out_col->mSampler = it->second->mDaeSampler2D;
01597 if ( it->second->mDaeSampler2D.get() == NULL)
01598 {
01599 VL_LOG_DEBUG << "- LoadWriterDae: malformed file: <texture texture=..> points to a <newparam> that does not contain <sampler2D>!\n";
01600 }
01601 }
01602 else
01603 {
01604 std::map< daeElementRef, ref<Image> >::iterator it = mImages.find(sampler2D_newparam);
01605 if ( it != mImages.end() )
01606 {
01607
01608 out_col->mSampler = new Dae::Sampler2D;
01609 out_col->mSampler->mDaeSurface = new Dae::Surface;
01610 out_col->mSampler->mDaeSurface->mImage = it->second;
01611 prepareTexture2D( out_col->mSampler.get() );
01612 VL_LOG_DEBUG << "- LoadWriterDae: malformed file: <texture texture=..> parameter points to an <image> instead of a <sampler2D>!\n"
01613 "VL will create a dummy sampler with the specified image.\n";
01614 }
01615 else
01616 {
01617 VL_LOG_DEBUG << "- LoadWriterDae: malformed file: <texture texture=..> could not be resolved to anything!\n";
01618 }
01619 }
01620
01621
01622 out_col->mTexCoord = color_or_texture->getTexture()->getTexcoord();
01623 }
01624 }
01625
01626 void DaeLoader::generateGeometry(Dae::Primitive* prim, const char* name)
01627 {
01628 VL_CHECK(prim->mIndexStride);
01629
01630 prim->mGeometry = new Geometry;
01631 if (name)
01632 prim->mGeometry->setObjectName(name);
01633
01634
01635 if(prim->mP.size() == 0 && prim->mType == Dae::PT_UNKNOWN && prim->mChannels.size())
01636 {
01637
01638 for(size_t i=0; i<prim->mChannels.size(); ++i)
01639 {
01640 if ( prim->mChannels[i]->mSource->count() != prim->mChannels[0]->mSource->count() )
01641 {
01642 VL_LOG_DEBUG << "- LoadWriterDae: cannot generate point cloud: channels have different sizes!\n";
01643 return;
01644 }
01645 if ( prim->mChannels[i]->mOffset != 0 )
01646 {
01647 VL_LOG_DEBUG << "- LoadWriterDae: cannot generate point cloud: channels must have offset == 0!\n";
01648 return;
01649 }
01650 }
01651
01652
01653 prim->mP.resize(1);
01654 prim->mP[0] = static_cast<domP*>(domP::create(mDAE).cast());
01655 prim->mP[0]->getValue().setCount( prim->mChannels[0]->mSource->count() );
01656 for (size_t i=0; i<prim->mChannels[0]->mSource->count(); ++i)
01657 prim->mP[0]->getValue()[i] = i;
01658 }
01659
01660 size_t total_index_count = 0;
01661 for(size_t ip=0; ip<prim->mP.size(); ++ip)
01662 total_index_count += prim->mP[ip]->getValue().getCount();
01663
01664 ref<ArrayUInt1> index_buffer = new ArrayUInt1;
01665 index_buffer->resize( total_index_count / prim->mIndexStride );
01666
01667 std::vector<GLint> vcount;
01668
01669
01670 std::set<Dae::Vert> vert_set;
01671 for(size_t ip=0, iidx=0; ip<prim->mP.size(); ++ip)
01672 {
01673 const domListOfUInts& p = prim->mP[ip]->getValue();
01674
01675 vcount.push_back( p.getCount() / prim->mIndexStride );
01676
01677 for(size_t ivert=0; ivert<p.getCount(); ivert+=prim->mIndexStride, ++iidx)
01678 {
01679 Dae::Vert vert;
01680
01681
01682 for(size_t ichannel=0; ichannel<prim->mChannels.size(); ++ichannel)
01683 vert.mAttribIndex[ichannel] = (size_t)p[ivert + prim->mChannels[ichannel]->mOffset];
01684
01685 size_t final_index = 0xFFFFFFFF;
01686
01687 std::set<Dae::Vert>::iterator it = vert_set.find(vert);
01688 if (it == vert_set.end())
01689 {
01690 vert.mIndex = final_index = vert_set.size();
01691 vert_set.insert(vert);
01692 }
01693 else
01694 final_index = it->mIndex;
01695
01696
01697 (*index_buffer)[iidx] = final_index;
01698 }
01699 }
01700
01701 if (vcount.size() == 1)
01702 {
01703
01704 ref<DrawElementsUInt> de;
01705 switch(prim->mType)
01706 {
01707 case Dae::PT_UNKNOWN: de = new DrawElementsUInt( PT_POINTS ); break;
01708 case Dae::PT_LINES: de = new DrawElementsUInt( PT_LINES ); break;
01709 case Dae::PT_LINE_STRIP: de = new DrawElementsUInt( PT_LINE_STRIP ); break;
01710 case Dae::PT_POLYGONS: de = new DrawElementsUInt( PT_POLYGON ); break;
01711 case Dae::PT_TRIFANS: de = new DrawElementsUInt( PT_TRIANGLE_FAN ); break;
01712 case Dae::PT_TRIANGLES: de = new DrawElementsUInt( PT_TRIANGLES ); break;
01713 case Dae::PT_TRISTRIPS: de = new DrawElementsUInt( PT_TRIANGLE_STRIP ); break;
01714 default:
01715 VL_TRAP()
01716 }
01717
01718 de->setIndexBuffer( index_buffer.get() );
01719 prim->mGeometry->drawCalls()->push_back( de.get() );
01720 }
01721 else
01722 {
01723
01724 ref<MultiDrawElementsUInt> mde;
01725 switch(prim->mType)
01726 {
01727 case Dae::PT_UNKNOWN: mde = new MultiDrawElementsUInt( PT_POINTS ); break;
01728 case Dae::PT_LINES: mde = new MultiDrawElementsUInt( PT_LINES ); break;
01729 case Dae::PT_LINE_STRIP: mde = new MultiDrawElementsUInt( PT_LINE_STRIP ); break;
01730 case Dae::PT_POLYGONS: mde = new MultiDrawElementsUInt( PT_POLYGON ); break;
01731 case Dae::PT_TRIFANS: mde = new MultiDrawElementsUInt( PT_TRIANGLE_FAN ); break;
01732 case Dae::PT_TRIANGLES: mde = new MultiDrawElementsUInt( PT_TRIANGLES ); break;
01733 case Dae::PT_TRISTRIPS: mde = new MultiDrawElementsUInt( PT_TRIANGLE_STRIP ); break;
01734 default:
01735 VL_TRAP()
01736 }
01737
01738 mde->setIndexBuffer( index_buffer.get() );
01739 mde->setCountVector( vcount );
01740 prim->mGeometry->drawCalls()->push_back( mde.get() );
01741 }
01742
01743
01744 size_t tex_unit = 0;
01745 for( size_t ich=0; ich<prim->mChannels.size(); ++ich )
01746 {
01747
01748 ref<ArrayAbstract> vert_attrib;
01749 float* ptr = NULL;
01750 float* ptr_end = NULL;
01751 switch(prim->mChannels[ich]->mSource->dataSize())
01752 {
01753 case 1:
01754 {
01755 ref<ArrayFloat1> array_f1 = new ArrayFloat1;
01756 vert_attrib = array_f1;
01757 array_f1->resize( vert_set.size() );
01758 ptr = array_f1->begin();
01759
01760 ptr_end = ptr + vert_set.size() * 1;
01761 break;
01762 }
01763 case 2:
01764 {
01765 ref<ArrayFloat2> array_f2 = new ArrayFloat2;
01766 vert_attrib = array_f2;
01767 array_f2->resize( vert_set.size() );
01768 ptr = array_f2->at(0).ptr();
01769
01770 ptr_end = ptr + vert_set.size() * 2;
01771 break;
01772 }
01773 case 3:
01774 {
01775 ref<ArrayFloat3> array_f3 = new ArrayFloat3;
01776 vert_attrib = array_f3;
01777 array_f3->resize( vert_set.size() );
01778 ptr = array_f3->at(0).ptr();
01779
01780 ptr_end = ptr + vert_set.size() * 3;
01781 break;
01782 }
01783 case 4:
01784 {
01785 ref<ArrayFloat4> array_f4 = new ArrayFloat4;
01786 vert_attrib = array_f4;
01787 array_f4->resize( vert_set.size() );
01788 ptr = array_f4->at(0).ptr();
01789
01790 ptr_end = ptr + vert_set.size() * 4;
01791 break;
01792 }
01793 default:
01794 Log::warning( Say("LoadWriterDae: input '%s' skipped because parameter count is more than 4.\n") << getSemanticString(prim->mChannels[ich]->mSemantic) );
01795 continue;
01796 }
01797
01798
01799 switch(prim->mChannels[ich]->mSemantic)
01800 {
01801 case Dae::IS_POSITION: prim->mGeometry->setVertexArray( vert_attrib.get() ); break;
01802 case Dae::IS_NORMAL: prim->mGeometry->setNormalArray( vert_attrib.get() ); break;
01803 case Dae::IS_COLOR: prim->mGeometry->setColorArray( vert_attrib.get() ); break;
01804 case Dae::IS_TEXCOORD: prim->mGeometry->setTexCoordArray( tex_unit++, vert_attrib.get() ); break;
01805 default:
01806 VL_LOG_DEBUG << ( Say("- LoadWriterDae: input semantic '%s' not supported.\n") << getSemanticString(prim->mChannels[ich]->mSemantic) );
01807 continue;
01808 }
01809
01810
01811 vert_attrib->setObjectName( String(Say("%s@SET%n") << getSemanticString(prim->mChannels[ich]->mSemantic) << prim->mChannels[ich]->mSet).toStdString().c_str() );
01812
01813
01814 for(std::set<Dae::Vert>::iterator it = vert_set.begin(); it != vert_set.end(); ++it)
01815 {
01816 const Dae::Vert& vert = *it;
01817 size_t idx = vert.mAttribIndex[ich];
01818 VL_CHECK(ptr + prim->mChannels[ich]->mSource->dataSize()*vert.mIndex < ptr_end);
01819 prim->mChannels[ich]->mSource->readData(idx, ptr +prim-> mChannels[ich]->mSource->dataSize()*vert.mIndex);
01820 }
01821 }
01822
01823
01824 if ( loadOptions()->fixBadNormals() && prim->mGeometry->normalArray() )
01825 {
01826 ref<ArrayFloat3> norm_old = vl::cast<ArrayFloat3>(prim->mGeometry->normalArray());
01827 VL_CHECK(norm_old);
01828
01829
01830 prim->mGeometry->computeNormals();
01831 ref<ArrayFloat3> norm_new = vl::cast<ArrayFloat3>(prim->mGeometry->normalArray());
01832 VL_CHECK(norm_new);
01833
01834 size_t flipped = 0;
01835 size_t degenerate = 0;
01836 for(size_t i=0; i<norm_new->size(); ++i)
01837 {
01838
01839 float l = norm_old->at(i).length();
01840 if ( l < 0.5f )
01841 {
01842 norm_old->at(i) = norm_new->at(i);
01843 ++degenerate;
01844 }
01845
01846 if ( l < 0.9f || l > 1.1f )
01847 {
01848 norm_old->at(i).normalize();
01849 ++degenerate;
01850 }
01851
01852 if ( dot(norm_new->at(i), norm_old->at(i)) < -0.1f )
01853 {
01854 norm_old->at(i) = -norm_old->at(i);
01855 ++flipped;
01856 }
01857 }
01858
01859
01860 if (degenerate || flipped)
01861 VL_LOG_DEBUG << ( Say("- LoadWriterDae: fixed bad normals in \"%s\": degenerate=%n, flipped=%n (out of %n).\n") << prim->mGeometry->objectName() << degenerate << flipped << norm_old->size() );
01862
01863
01864 prim->mGeometry->setNormalArray(norm_old.get());
01865 }
01866
01867
01868
01869
01870 }
01871
01872 void DaeLoader::parseAsset(domElement* root)
01873 {
01874 domElement* asset_el = root->getChild("asset");
01875 if (asset_el)
01876 {
01877 domAsset* asset = static_cast<domAsset*>(asset_el);
01878
01879
01880 if (asset->getUp_axis())
01881 {
01882 if( asset->getUp_axis()->getValue() == UPAXISTYPE_X_UP )
01883 {
01884
01885 mUpMatrix.setX( vec3( 0, 1, 0) );
01886 mUpMatrix.setY( vec3(-1, 0, 0) );
01887 mUpMatrix.setZ( vec3( 0, 0, 1) );
01888 }
01889 else
01890 if( asset->getUp_axis()->getValue() == UPAXISTYPE_Z_UP )
01891 {
01892
01893 mUpMatrix.setX( vec3(1, 0, 0) );
01894 mUpMatrix.setY( vec3(0, 0,-1) );
01895 mUpMatrix.setZ( vec3(0, 1, 0) );
01896 }
01897 }
01898
01899
01900 mInvertTransparency = false;
01901 mAssumeOpaque = false;
01902 if (loadOptions()->invertTransparency() == LoadWriterDae::LoadOptions::TransparencyInvert)
01903 mInvertTransparency = true;
01904 else
01905 if (loadOptions()->invertTransparency() == LoadWriterDae::LoadOptions::TransparencyAuto)
01906 {
01907 for(size_t i=0; i<asset->getContributor_array().getCount(); ++i)
01908 {
01909 const char* tool = asset->getContributor_array()[i]->getAuthoring_tool()->getValue();
01910
01911 if (!tool)
01912 continue;
01913
01914 VL_LOG_DEBUG << "- Authoring tool = " << tool << "\n";
01915
01916
01917
01918 const char* google_str = strstr(tool, "Google SketchUp");
01919 size_t google_str_len = strlen("Google SketchUp");
01920 if ( google_str )
01921 {
01922 if ( strlen(google_str) > google_str_len )
01923 {
01924 float version = 1000;
01925 if ( sscanf( google_str + google_str_len, "%f", &version) )
01926 {
01927 version = version * 100 + 0.5f;
01928 if (version < 710)
01929 mInvertTransparency = true;
01930 }
01931 else
01932 {
01933
01934 mAssumeOpaque = true;
01935 }
01936 }
01937 else
01938 {
01939
01940 mAssumeOpaque = true;
01941 }
01942 break;
01943 }
01944
01945
01946
01947
01948
01949 const char* colladamaya_str = strstr(tool, "ColladaMaya v");
01950 size_t colladamaya_str_len = strlen("ColladaMaya v");
01951 if ( colladamaya_str )
01952 {
01953 float version = 1000;
01954 if ( strlen(colladamaya_str) > colladamaya_str_len )
01955 {
01956 if ( sscanf( colladamaya_str + colladamaya_str_len, "%f", &version) )
01957 {
01958 version = version * 100 + 0.5f;
01959 if (version < 303)
01960 mAssumeOpaque = true;
01961 }
01962 else
01963 {
01964
01965 mAssumeOpaque = true;
01966 }
01967 }
01968 else
01969 {
01970
01971 mAssumeOpaque = true;
01972 }
01973 }
01974
01975 const char* colladamax_str = strstr(tool, "ColladaMax v");
01976 size_t colladamax_str_len = strlen("ColladaMax v");
01977 if ( colladamax_str )
01978 {
01979 float version = 1000;
01980 if ( strlen(colladamax_str) > colladamax_str_len )
01981 {
01982 if ( sscanf( colladamax_str + colladamax_str_len, "%f", &version) )
01983 {
01984 version = version * 100 + 0.5f;
01985 if (version < 303)
01986 mAssumeOpaque = true;
01987 }
01988 else
01989 {
01990
01991 mAssumeOpaque = true;
01992 }
01993 }
01994 else
01995 {
01996
01997 mAssumeOpaque = true;
01998 }
01999 }
02000
02001
02002 if ( strstr(tool, "VCGLib | MeshLab") )
02003 {
02004 mInvertTransparency = true;
02005 }
02006
02007 VL_LOG_DEBUG << "- Invert transparency = " << (mInvertTransparency ? "yes" : "no.") << "\n";
02008 VL_LOG_DEBUG << "- Assume opaque = " << (mAssumeOpaque? "yes" : "no.") << "\n";
02009
02010
02011 break;
02012 }
02013 }
02014 }
02015 }