# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/plugins/COLLADA/DaeLoader.cpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.org                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    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   // default material
    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     // copy over VERTEX inputs with the current offset and set
    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         // if the source is NULL getSource() has already issued an error.
    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   // try to reuse the geometry in the library
    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   // add to dictionary
    00162   ref<Dae::Mesh> dae_mesh = new Dae::Mesh;
    00163   mMeshes[geometry] = dae_mesh;
    00164
    00165   // vertices
    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     // if the source is NULL getSource() already issued an error.
    00181     if (!dae_input->mSource)
    00182       continue;
    00183
    00184     dae_mesh->mVertexInputs.push_back(dae_input);
    00185   }
    00186
    00187   // --- --- ---- primitives ---- --- ---
    00188
    00189   // NOTE: for the moment we generate one Geometry for each primitive but we should try to generate
    00190   // one single set of vertex attribute array for each input semantic and recycle it if possible.
    00191   // Unfortunately COLLADA makes this trivial task impossible to achieve.
    00192
    00193   // --- ---- triangles ---- ---
    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     // --- input ---
    00205     domInputLocalOffset_Array input_arr = triangles->getInput_array();
    00206     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00207
    00208     // --- ---- p ---- ---
    00209     dae_primitive->mP.push_back( triangles->getP() );
    00210
    00211     // --- ---- material ---- ---
    00212     dae_primitive->mMaterial = triangles->getMaterial() ? triangles->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00213
    00214     // --- ---- generates the geometry ---- ---
    00215     generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
    00216   }
    00217
    00218   // --- ---- triangles fan ---- ---
    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     // --- input ---
    00230     domInputLocalOffset_Array input_arr = trifan->getInput_array();
    00231     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00232
    00233     // --- ---- p ---- ---
    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     // --- ---- material ---- ---
    00238     dae_primitive->mMaterial = trifan->getMaterial() ? trifan->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00239
    00240     // --- ---- generates the geometry ---- ---
    00241     generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
    00242   }
    00243
    00244   // --- ---- triangle strip ---- ---
    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     // --- input ---
    00256     domInputLocalOffset_Array input_arr = tristrip->getInput_array();
    00257     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00258
    00259     // --- ---- p ---- ---
    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     // --- ---- material ---- ---
    00264     dae_primitive->mMaterial = tristrip->getMaterial() ? tristrip->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00265
    00266     // --- ---- generates the geometry ---- ---
    00267     generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
    00268   }
    00269
    00270   // --- ---- polygons ---- ---
    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     // --- input ---
    00282     domInputLocalOffset_Array input_arr = polygon->getInput_array();
    00283     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00284
    00285     // --- ---- p ---- ---
    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     // --- ---- material ---- ---
    00290     dae_primitive->mMaterial = polygon->getMaterial() ? polygon->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00291
    00292     // --- ---- generates the geometry ---- ---
    00293     generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
    00294   }
    00295
    00296   // --- ---- polylists ---- ---
    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     // --- input ---
    00308     domInputLocalOffset_Array input_arr = polylist->getInput_array();
    00309     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00310
    00311     // --- ---- p ---- ---
    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     // --- ---- material ---- ---
    00325     dae_primitive->mMaterial = polylist->getMaterial() ? polylist->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00326
    00327     // --- ---- generates the geometry ---- ---
    00328     generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
    00329   }
    00330
    00331   // --- ---- linestrips ---- ---
    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     // --- input ---
    00343     domInputLocalOffset_Array input_arr = linestrip->getInput_array();
    00344     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00345
    00346     // --- ---- p ---- ---
    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     // --- ---- material ---- ---
    00351     dae_primitive->mMaterial = linestrip->getMaterial() ? linestrip->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00352
    00353     // --- ---- generates the geometry ---- ---
    00354     generateGeometry( dae_primitive.get(), geometry->getAttribute("id").c_str() );
    00355   }
    00356
    00357   // --- ---- lines ---- ---
    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     // --- input ---
    00369     domInputLocalOffset_Array input_arr = line->getInput_array();
    00370     parseInputs(dae_primitive.get(), input_arr, dae_mesh->mVertexInputs);
    00371
    00372     // --- ---- p ---- ---
    00373     dae_primitive->mP.push_back( line->getP() );
    00374
    00375     // --- ---- material ---- ---
    00376     dae_primitive->mMaterial = line->getMaterial() ? line->getMaterial() : VL_NO_MATERIAL_SPECIFIED;
    00377
    00378     // --- ---- generates the geometry ---- ---
    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     // we support up to 32 parameters for a single accessor
    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     // add to source library for quick access later
    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   // VL_CHECK(mat->mDaeEffect->mDaeTechniqueCOMMON)
    00436
    00437   ref<Effect> fx = new Effect;
    00438   fx->shader()->enable(EN_DEPTH_TEST);
    00439
    00440   // very basic material setup
    00441   if (mat->mDaeEffect->mDaeTechniqueCOMMON)
    00442   {
    00443     Dae::TechniqueCOMMON* common_tech =mat->mDaeEffect->mDaeTechniqueCOMMON.get();
    00444
    00445     // compute the actual tranparency
    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     // enable lighting only if required
    00457     if ( use_lighting )
    00458     {
    00459       fx->shader()->enable(EN_LIGHTING);
    00460
    00461       // mic fixme: most of .dae files I tested require this even if no double_sided flag is set.
    00462       // fx->shader()->gocLightModel()->setTwoSide(true);
    00463
    00464       // material sanity checks: these are needed only when using fixed function pipeline
    00465       common_tech->mShininess = vl::clamp(common_tech->mShininess, 0.0f, 128.0f);
    00466
    00467       // mic fixme: this vl::Effect can be put in mDaeTechniqueCOMMON and shared among all the materials that use it.
    00468       fx->shader()->gocMaterial()->setDiffuse  ( common_tech->mDiffuse.mColor  ); // this is fuchsia by default
    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       // if a texture is bound to the diffuse channel use it
    00475       // mic fixme: for the moment we support only one texture, we also assume the texture coords #0 are the right ones...
    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       // alpha blending management
    00483
    00484       // sets the alpha value of all material colors, front and back
    00485       fx->shader()->gocMaterial()->multiplyTransparency( transparency );
    00486     }
    00487     else
    00488     if ( strstr(mat->mDaeEffect->objectName().c_str(), "constant:") )
    00489     {
    00490
    00491       // constant can have only emission, check if there is a texture attached to it and use it
    00492       // mic fixme: for the moment we support only one texture, we also assume the texture coords #0 are the right ones...
    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         // this is already the default: fx->shader()->gocColor()->setColor( vl::white );
    00497       }
    00498       else
    00499         fx->shader()->gocColor()->setValue( common_tech->mEmission.mColor );
    00500     }
    00501
    00502     // enable alpha blending if material is transparent or alpha is coming from the diffuse texture
    00503     // NOTE: to be pedantic with the specs we should enabled the alpha blending if common_tech->mBlendingOn == true however
    00504     // applications and exporters have historically misused the <transparency> and <transparent> tags...
    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     // to be correct we should do this but most models are not made to render correctly this way...
    00510 #if 0
    00511     if (!mat->mDaeEffect->mDoubleSided)
    00512       fx->shader()->enable(EN_CULL_FACE); // no two sidelighting, yes culling
    00513     else
    00514     if (use_lighting)
    00515       fx->shader()->gocLightModel()->setTwoSide(true); // yes two side lighting, no culling
    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   // map symbols to actual materials
    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           // mic fixme: issue warning
    00545           // VL_CHECK( material_map.find(material_instances[i]->getSymbol()) == material_map.end() )
    00546           // VL_CHECK( material_instances[i]->getSymbol() )
    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   // now we need to instance the material
    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     // --- --- --- parse this node --- --- ---
    00595
    00596     // create new node and add it to the library
    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     // parse geometries
    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       // generate the Actors belonging to this node with their own material
    00615       bindMaterials(this_node.get(), dae_mesh.get(), geometries[i]->getBind_material());
    00616     }
    00617
    00618     // parse controllers
    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         // generate the Actors belonging to this node with their own material
    00641         bindMaterials(this_node.get(), dae_mesh.get(), controllers[i]->getBind_material());
    00642       }
    00643     }
    00644
    00645     // note: transforms are post-multiplied in the order in which they are specified (as if they were sub-nodes)
    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         // mic fixme: support skew
    00693         // domSkew* skew = static_cast<domSkew*>(child);
    00694         Log::error("LoadWriterDae: <skew> transform not supported yet. Call me if you know how to compute it.\n");
    00695       }
    00696     }
    00697
    00698     // parse lights
    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     // --- --- --- parse children --- --- ---
    00709
    00710     // parse instance nodes
    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     // parse proper children
    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   // load COLLADA file as a string.
    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   // --- parse the visual scene ---
    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   // --- fill the resource database and final setup ---
    00769
    00770   // --- transform setup ---
    00771   // Up vector
    00772   // Note that we don't touch the local space vertices and the intermediate matrices,
    00773   // for proper reorientation of matrices and geometry the up-vector conditioner in
    00774   // Refinery should do the job.
    00775   mScene->mTransform->preMultiply( mUpMatrix );
    00776   // Setup world matrices
    00777   mScene->mTransform->computeWorldMatrixRecursive();
    00778
    00779   // --- light setup ---
    00780   // Computes position and direction of lights, sorts them (direction -> spot -> point),
    00781   // adds them to the resource database.
    00782   setupLights();
    00783
    00784   // return the Actors
    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       // add actor to the resources
    00792       mResources->resources().push_back( actor );
    00793
    00794       // *** flatten transform hierarchy ***
    00795       if ( loadOptions()->flattenTransformHierarchy() )
    00796         actor->transform()->removeFromParent();
    00797
    00798       // *** merge draw calls ***
    00799       if (loadOptions()->mergeDrawCalls())
    00800       {
    00801         Geometry* geom = actor->lod(0)->as<Geometry>();
    00802         if (geom)
    00803         {
    00804           // first merge all tristrips
    00805           ref<DrawCall> tristrips = geom->mergeTriangleStrips();
    00806           // keep it for later
    00807           geom->drawCalls()->erase( tristrips.get() );
    00808
    00809           // merge all non-tristrips
    00810           geom->mergeDrawCallsWithTriangles(PT_UNKNOWN);
    00811
    00812           // put back the tristrips
    00813           if (tristrips.get())
    00814             geom->drawCalls()->push_back( tristrips.get() );
    00815         }
    00816       }
    00817
    00818       // *** check for transforms that require normal rescaling ***
    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         // Log::warning("Detected mesh with scaled transform: enabled normal renormalization.\n");
    00826         if ( actor->effect()->shader()->isEnabled(vl::EN_LIGHTING) )
    00827           actor->effect()->shader()->enable(vl::EN_NORMALIZE); // or vl::EN_RESCALE_NORMAL
    00828       }
    00829
    00830       // *** light association & normal computation (only if lighting is on!) ***
    00831       if ( actor->effect()->shader()->isEnabled(EN_LIGHTING) )
    00832       {
    00833         // *** light association ***
    00834         // crete new effect/shader with it's own light set
    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        // *** compute missing normals ***
    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     // process encoded character
    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       // encoding error
    00894       if (hex1 == -1 || hex2 == -1)
    00895       {
    00896         // insert percent code as it is
    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     // load images
    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       // <profile_COMMON>
    00961       if ( profiles[i]->typeID() == domProfile_COMMON::ID() )
    00962       {
    00963         domProfile_COMMON* common = static_cast<domProfile_COMMON*>(profiles[i].cast());
    00964
    00965         // --- parse <newparam> ---
    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           // insert in the map se can resolve references to <sampler2D> and <surface>
    00974           mDaeNewParams[newparam.cast()] = dae_newparam;
    00975
    00976           // --- <surface> ---
    00977           // mic fixme: for the moment we support only single image 2D surfaces
    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           // --- <sampler2D> ---
    01007           if (newparam->getSampler2D())
    01008           {
    01009             domFx_sampler2D_commonRef sampler2D = newparam->getSampler2D();
    01010
    01011             dae_newparam->mDaeSampler2D = new Dae::Sampler2D;
    01012
    01013             // --- <source> ---
    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             // --- <minfilter> ---
    01034             if( sampler2D->getMinfilter() )
    01035             {
    01036               dae_newparam->mDaeSampler2D->mMinFilter = translateSampleFilter( sampler2D->getMinfilter()->getValue() );
    01037             }
    01038
    01039
    01040             // --- <magfilter> ---
    01041             if( sampler2D->getMagfilter() )
    01042             {
    01043               dae_newparam->mDaeSampler2D->mMagFilter = translateSampleFilter( sampler2D->getMagfilter()->getValue() );
    01044             }
    01045
    01046             // --- <wrap_s> ---
    01047             if (sampler2D->getWrap_s())
    01048             {
    01049               dae_newparam->mDaeSampler2D->mWrapS = translateWrapMode( sampler2D->getWrap_s()->getValue() );
    01050             }
    01051
    01052             // --- <wrap_t> ---
    01053             if (sampler2D->getWrap_t())
    01054             {
    01055               dae_newparam->mDaeSampler2D->mWrapT = translateWrapMode( sampler2D->getWrap_t()->getValue() );
    01056             }
    01057
    01058             // prepare vl::Texture for creation with the given parameters
    01059             prepareTexture2D(dae_newparam->mDaeSampler2D.get());
    01060           }
    01061
    01062           // --- <float>, <float2>, <float3>, <floa4> ---
    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         // <technique sid="COMMON">
    01088
    01089         // --- parse technique ---
    01090         if (common->getTechnique()->getBlinn())
    01091         {
    01092           // track effect name
    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           // track effect name
    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           // track effect name
    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           // track effect name
    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         // trasparency override options
    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; // mic fixme: metti questo dentro Dae:: namespace
    01230         }
    01231         else
    01232         if(mInvertTransparency)
    01233         {
    01234           dae_effect->mDaeTechniqueCOMMON->mTransparency = 1.0f - dae_effect->mDaeTechniqueCOMMON->mTransparency;
    01235           // and don't trust <transparent> values...
    01236           dae_effect->mDaeTechniqueCOMMON->mTransparent.mColor = fvec4(0, 0, 0, 1);
    01237           dae_effect->mDaeTechniqueCOMMON->mOpaqueMode = Dae::OM_A_ONE;
    01238         }
    01239
    01240         // <extra>
    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     // this is actually irrelevant since the diffuse and specular colors are zeroed.
    01419     light->setPosition( fvec4( 0, 0, 0, 1) );
    01420
    01421     // just for clarity, no attenuation
    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   // generate light meshes
    01433   if (loadOptions()->lightMeshSize())
    01434   {
    01435     for(size_t i=0; i<mLights.size(); ++i)
    01436     {
    01437       // spot light
    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       // directional light
    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       // point light
    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       // ambient light
    01477       {
    01478         ref<Geometry> light_mesh = vl::makeTorus( vec3(0,0,0), loadOptions()->lightMeshSize(), loadOptions()->lightMeshSize()/4, 8, 14);
    01479         light_mesh->setNormalArray(NULL); // remove normals
    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       // ambient lights first
    01495       if (a->ambient() != b->ambient())
    01496         return b->ambient() < a->ambient();
    01497       else
    01498       // directional lights first
    01499       if (a->position().w() != b->position().w())
    01500         return a->position().w() < b->position().w();
    01501       else
    01502       // point lights first, spotlights last
    01503         return a->spotCutoff() > b->spotCutoff();
    01504     }
    01505   };
    01506
    01507   std::sort(mLights.begin(), mLights.end(), dummy::light_sorter);
    01508
    01509   // set light indices and adds to the resource database
    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   // default light if no lights were present in the scene or exportLights() == false
    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     // <texture texture="...">
    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         // create dummy sampler
    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     // <texture texcoord="...">
    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   // no primitives where specified so we treat it as a cloud of points simulating a single increasing <p>
    01635   if(prim->mP.size() == 0 && prim->mType == Dae::PT_UNKNOWN && prim->mChannels.size())
    01636   {
    01637     // some sanity checks
    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     // generate dummy <p>
    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   // generate index buffer for DrawElements or MultiDrawElements.
    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       // fill vertex info
    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       // retrieve/insert the vertex
    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       // this is the actual index
    01697       (*index_buffer)[iidx] = final_index;
    01698     }
    01699   }
    01700
    01701   if (vcount.size() == 1)
    01702   {
    01703     // use DrawElements
    01704     ref<DrawElementsUInt> de;
    01705     switch(prim->mType)
    01706     {
    01707       case Dae::PT_UNKNOWN:    de = new DrawElementsUInt( PT_POINTS ); break; // of course we can do better than this but we would need a lot of extra logic
    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     // use MultiDrawElements
    01724     ref<MultiDrawElementsUInt> mde;
    01725     switch(prim->mType)
    01726     {
    01727       case Dae::PT_UNKNOWN:    mde = new MultiDrawElementsUInt( PT_POINTS ); break; // of course we can do better than this but we would need a lot of extra logic
    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   // generate new vertex attrib info and install data
    01744   size_t tex_unit = 0;
    01745   for( size_t ich=0; ich<prim->mChannels.size(); ++ich )
    01746   {
    01747     // init data storage for this channel
    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         // debug
    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         // debug
    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         // debug
    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         // debug
    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     // install vertex attribute
    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     // name it as TEXCOORD@SET0 etc. to be recognized when binding (not used yet)
    01811     vert_attrib->setObjectName( String(Say("%s@SET%n") << getSemanticString(prim->mChannels[ich]->mSemantic) << prim->mChannels[ich]->mSet).toStdString().c_str() );
    01812
    01813     // fill the vertex attribute array
    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   // --- fix bad normals ---
    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     // recompute normals
    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       // compare VL normals with original ones
    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     // mic fixme: issue these things as debug once things got stable
    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     // reinstall fixed normals
    01864     prim->mGeometry->setNormalArray(norm_old.get());
    01865   }
    01866
    01867    // disabled: we transform the root matrix instead
    01868    // --- orient geometry based on up vector ---
    01869    // prim->mGeometry->transform((mat4)mUpMatrix);
    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     // up vector
    01880     if (asset->getUp_axis())
    01881     {
    01882       if( asset->getUp_axis()->getValue() == UPAXISTYPE_X_UP )
    01883       {
    01884         // X_UP Negative y Positive x Positive z
    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         // Z_UP Positive x Positive z Negative y
    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     // try to fix the transparency written by crappy tools
    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         // Google SketchUp before 7.1 requires <transparency> inversion.
    01917         // see http://www.collada.org/public_forum/viewtopic.php?f=12&t=1667
    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               // don't trust Google SketchUp if we cannot read the version
    01934               mAssumeOpaque = true;
    01935             }
    01936           }
    01937           else
    01938           {
    01939             // don't trust Google SketchUp if we cannot read the version
    01940             mAssumeOpaque = true;
    01941           }
    01942           break;
    01943         }
    01944
    01945         // See https://collada.org/mediawiki/index.php/ColladaMaya#ColladaMaya_3.03
    01946         // - "Data exported with previous versions of our COLLADA tools may import with inverted transparency in ColladaMax 3.03 and ColladaMaya 3.03."
    01947         // - Actually ColladaMax/ColladaMaya before 3.03 use unpredictable combinations of <transparent> and <transparency>, so... we assume opaque.
    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               // don't trust ColladaMaya if we cannot read the version
    01965               mAssumeOpaque = true;
    01966             }
    01967           }
    01968           else
    01969           {
    01970             // don't trust ColladaMaya if we cannot read the version
    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               // don't trust ColladaMax if we cannot read the version
    01991               mAssumeOpaque = true;
    01992             }
    01993           }
    01994           else
    01995           {
    01996             // don't trust ColladaMax if we cannot read the version
    01997             mAssumeOpaque = true;
    01998           }
    01999         }
    02000
    02001         // MeshLab seem to flip the transparency also now.
    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         // stop at the first contributor
    02011         break;
    02012       }
    02013     }
    02014   }
    02015 }

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:40.
Permission is granted to use this page to write and publish articles regarding Visualization Library.