From 1feea279a5f08853466347ded5d4d9c0eaff9f9d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 23 Mar 2012 11:16:01 +0000 Subject: [PATCH] From Luc Frauciel, "I've encoutered a nasty group of dae which are incompatible with dae plugins (and probably collada schema ) in 4 different ways : 1) they use direct link to texture -> this is already handle by current plugin : OK 2) they defined colors with only 3 color components -> it leads to a crash when trying to acces to the fourth component I fixed that 3) they contain empty primitive lists -> reading is ok, but osgviewer crashes when trying to display the geometries The reason is that osg assume that DrawElementsare never empty (blunt acces to DrawElements.front() in PrimitiveSet.cpp) I corrected this (on the plugin side), but I wonder : Is it the responsability of plugins to create non empty DrawElements, or of osg core not to crash when they occur ? If the responsability is on the osg core side, I can submit a patch to PrimitiveSet.cpp regarding that aspect. 4) they use a material binding scheme not supported by the plugin ->I've implemented a mechanism to handle this binding scheme You will also find in the patch an example of these evil dae and comments on the offending elements. They seems to be produced by ComputaMaps (www.computamaps.com) They load well in Google Earth " --- src/osgPlugins/dae/daeRGeometry.cpp | 11 +++++++-- src/osgPlugins/dae/daeRMaterials.cpp | 36 ++++++++++++++++++++++------ src/osgPlugins/dae/daeReader.h | 2 ++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/osgPlugins/dae/daeRGeometry.cpp b/src/osgPlugins/dae/daeRGeometry.cpp index 9d457f0fd..257f9d301 100644 --- a/src/osgPlugins/dae/daeRGeometry.cpp +++ b/src/osgPlugins/dae/daeRGeometry.cpp @@ -462,7 +462,7 @@ void daeReader::processSinglePPrimitive(osg::Geode* geode, osg::Geometry *geometry = new osg::Geometry(); if (NULL != group->getMaterial()) geometry->setName(group->getMaterial()); - geode->addDrawable( geometry ); + osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(mode); geometry->addPrimitiveSet(pDrawElements); @@ -472,7 +472,11 @@ void daeReader::processSinglePPrimitive(osg::Geode* geode, std::vector > indexLists; resolveMeshArrays(domPArray, group->getInput_array(), pDomMesh, geometry, sources, indexLists); - pDrawElements->asVector().swap(indexLists.front()); + if (indexLists.front().size()) + { + pDrawElements->asVector().swap(indexLists.front()); + geode->addDrawable( geometry ); + } } template< typename T > @@ -945,6 +949,9 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray, { if (daeElement* texcoord_source = texcoord_sources[texcoord_set]) { + std::string id = std::string("#") + texcoord_source->getID(); + //We keep somewhere the mapping between daeElement id and created arrays + _texCoordIdMap.insert(std::pair(id,texcoord_set)); // 2D Texcoords osg::Geometry::ArrayData arrayData( createGeometryData(sources[texcoord_source], vertexIndicesIndexMap, readDoubleTexcoords, texcoord_set) ); if (arrayData.array.valid()) diff --git a/src/osgPlugins/dae/daeRMaterials.cpp b/src/osgPlugins/dae/daeRMaterials.cpp index a5efa8201..5e73fdf9e 100644 --- a/src/osgPlugins/dae/daeRMaterials.cpp +++ b/src/osgPlugins/dae/daeRMaterials.cpp @@ -584,7 +584,7 @@ bool daeReader::processColorOrTextureType(const osg::StateSet* ss, if (cot->getColor() != NULL ) { domFloat4 &f4 = cot->getColor()->getValue(); - mat->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) ); + mat->setEmission( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], (f4.getCount()==4)? f4[3] : 1.0 ) ); retVal = true; } else if (cot->getParam() != NULL) @@ -616,7 +616,7 @@ bool daeReader::processColorOrTextureType(const osg::StateSet* ss, if (cot->getColor() != NULL ) { domFloat4 &f4 = cot->getColor()->getValue(); - mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) ); + mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], (f4.getCount()==4)? f4[3] : 1.0 ) ); retVal = true; } else if (cot->getParam() != NULL) @@ -646,10 +646,10 @@ bool daeReader::processColorOrTextureType(const osg::StateSet* ss, } else if (channel == osg::Material::DIFFUSE ) { - if (cot->getColor() != NULL ) + if (cot->getColor() != NULL) { domFloat4 &f4 = cot->getColor()->getValue(); - mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) ); + mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], (f4.getCount()==4)? f4[3] : 1.0 ) ); retVal = true; } else if (cot->getTexture() != NULL) @@ -700,7 +700,7 @@ bool daeReader::processColorOrTextureType(const osg::StateSet* ss, if (cot->getColor() != NULL ) { domFloat4 &f4 = cot->getColor()->getValue(); - mat->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], f4[3] ) ); + mat->setSpecular( osg::Material::FRONT_AND_BACK, osg::Vec4( f4[0], f4[1], f4[2], (f4.getCount()==4)? f4[3] : 1.0 ) ); retVal = true; } else if (cot->getParam() != NULL) @@ -1305,9 +1305,31 @@ bool daeReader::copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geo if (k == bvia.getCount()) { OSG_WARN << "Failed to find matching for " << texCoordSetName << std::endl; - if (cachedGeometry->getNumTexCoordArrays()) + + //bind_vertex_input failed, we try bind + const domInstance_material::domBind_Array &ba = im->getBind_array(); + for (k = 0; k < ba.getCount(); k++) { - clonedGeometry->setTexCoordData(localTextureUnit, cachedGeometry->getTexCoordData(0)); + if (!strcmp(ba[k]->getSemantic(), texCoordSetName.c_str()) ) + { + IdToCoordIndexMap::const_iterator it = _texCoordIdMap.find(ba[k]->getTarget()); + if (it!=_texCoordIdMap.end()&& (cachedGeometry->getNumTexCoordArrays()>it->second)) + { + clonedGeometry->setTexCoordData(localTextureUnit, cachedGeometry->getTexCoordData(it->second)); + } + else + { + OSG_WARN << "Texture coordinate set " << ba[k]->getTarget() << " not found." << std::endl; + } + break; + } + } + if (k == ba.getCount()) + { + if (cachedGeometry->getNumTexCoordArrays()) + { + clonedGeometry->setTexCoordData(localTextureUnit, cachedGeometry->getTexCoordData(0)); + } } } return true; diff --git a/src/osgPlugins/dae/daeReader.h b/src/osgPlugins/dae/daeReader.h index 10d043907..7acd498ae 100644 --- a/src/osgPlugins/dae/daeReader.h +++ b/src/osgPlugins/dae/daeReader.h @@ -245,6 +245,7 @@ public: typedef std::map > domNodeOsgSkeletonMap; typedef std::map > TextureParametersMap; typedef std::map, std::string> TextureToCoordSetMap; + typedef std::map IdToCoordIndexMap; typedef std::map< daeElement*, domSourceReader > SourceMap; typedef std::map< int, osg::IntArray*, std::less > IndexMap; @@ -403,6 +404,7 @@ private: MaterialStateSetMap _materialMap2; TextureParametersMap _textureParamMap; TextureToCoordSetMap _texCoordSetMap; + IdToCoordIndexMap _texCoordIdMap; domInstance_controllerList _skinInstanceControllers; OldToNewIndexMap _oldToNewIndexMap;