From fc32aa491815fd54df5deb99bb30ed83c1bd8fe6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 19 Jan 2011 10:31:49 +0000 Subject: [PATCH] From Sukender, "Added ability for writer to read from Vec3/4d/f. Plugin now warns if it finds another type of data" --- src/osgPlugins/dae/ReaderWriterDAE.cpp | 4 +- src/osgPlugins/dae/daeRAnimations.cpp | 26 +- src/osgPlugins/dae/daeRGeometry.cpp | 156 ++++++--- src/osgPlugins/dae/daeRSkinning.cpp | 52 ++- src/osgPlugins/dae/daeReader.cpp | 3 +- src/osgPlugins/dae/daeReader.h | 3 +- src/osgPlugins/dae/daeWGeometry.cpp | 417 ++++++++++--------------- src/osgPlugins/dae/daeWriter.cpp | 47 +++ src/osgPlugins/dae/daeWriter.h | 55 ++-- src/osgPlugins/dae/domSourceReader.cpp | 119 +++++-- src/osgPlugins/dae/domSourceReader.h | 42 ++- 11 files changed, 551 insertions(+), 373 deletions(-) diff --git a/src/osgPlugins/dae/ReaderWriterDAE.cpp b/src/osgPlugins/dae/ReaderWriterDAE.cpp index 91e7be68d..950359af4 100644 --- a/src/osgPlugins/dae/ReaderWriterDAE.cpp +++ b/src/osgPlugins/dae/ReaderWriterDAE.cpp @@ -57,7 +57,9 @@ ReaderWriterDAE::readNode(const std::string& fname, pDAE = new DAE; } - osgDAE::daeReader daeReader(pDAE, options && options->getOptionString().find("StrictTransparency") != std::string::npos ) ; + osgDAE::daeReader daeReader(pDAE, + options && options->getOptionString().find("StrictTransparency") != std::string::npos, + options ? options->getPrecisionHint() : 0 ) ; // Convert file name to URI std::string fileURI = ConvertFilePathToColladaCompatibleURI(fileName); diff --git a/src/osgPlugins/dae/daeRAnimations.cpp b/src/osgPlugins/dae/daeRAnimations.cpp index 6f2548c22..80757ee3c 100644 --- a/src/osgPlugins/dae/daeRAnimations.cpp +++ b/src/osgPlugins/dae/daeRAnimations.cpp @@ -604,10 +604,13 @@ daeReader::ChannelPart* daeReader::processSampler(domChannel* pDomChannel, Sourc } } + //const bool readDoubleKeyframes = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_KEYFRAMES) != 0; + static const bool readDoubleKeyframes = false; + findInputSourceBySemantic(domInputArray, COMMON_PROFILE_INPUT_OUTPUT, output_source, &tmp); findInputSourceBySemantic(domInputArray, COMMON_PROFILE_INPUT_IN_TANGENT, output_intangent_source, &tmp); findInputSourceBySemantic(domInputArray, COMMON_PROFILE_INPUT_OUT_TANGENT, output_outtangent_source, &tmp); - domSourceReader::ArrayType arrayType = sources[output_source].getArrayType(); + domSourceReader::ArrayType arrayType = sources[output_source].getArrayType(readDoubleKeyframes); struct InterpTypeName { @@ -711,6 +714,27 @@ daeReader::ChannelPart* daeReader::processSampler(domChannel* pDomChannel, Sourc sources[output_outtangent_source].getVec4Array(), interpolationType); break; + case domSourceReader::Vec2d: + keyframes = makeKeyframes(pOsgTimesArray, + sources[output_source].getVec2dArray(), + sources[output_intangent_source].getVec2dArray(), + sources[output_outtangent_source].getVec2dArray(), + interpolationType); + break; + case domSourceReader::Vec3d: + keyframes = makeKeyframes(pOsgTimesArray, + sources[output_source].getVec3dArray(), + sources[output_intangent_source].getVec3dArray(), + sources[output_outtangent_source].getVec3dArray(), + interpolationType); + break; + case domSourceReader::Vec4d: + keyframes = makeKeyframes(pOsgTimesArray, + sources[output_source].getVec4dArray(), + sources[output_intangent_source].getVec4dArray(), + sources[output_outtangent_source].getVec4dArray(), + interpolationType); + break; case domSourceReader::Matrix: keyframes = makeKeyframes(pOsgTimesArray, sources[output_source].getMatrixArray(), diff --git a/src/osgPlugins/dae/daeRGeometry.cpp b/src/osgPlugins/dae/daeRGeometry.cpp index 328ffdd0a..0ba50ba25 100644 --- a/src/osgPlugins/dae/daeRGeometry.cpp +++ b/src/osgPlugins/dae/daeRGeometry.cpp @@ -794,48 +794,99 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray, } } - if (const osg::Vec3Array* source = sources[position_source].getVec3Array()) +// Local defines to make te code a bit more readable +// Sukender: This is not a very clean way to code, I know, but else the code is unmaintanable. +#define FOREACH_INDEX for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); it != end; ++it) +//#define FOREACH_INDEX for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(); it != vertexIndicesIndexMap.end(); ++it) +#define ENSURE_VECTOR_SIZE(arrayName, text) if (arrayName) { \ + if (arrayName->size() > nbVertices) OSG_NOTIFY(osg::NOTICE) << "More " #text " coordinates than vertices found. Result may not be what expected." << std::endl; \ + if (arrayName->size() < nbVertices) { \ + OSG_NOTIFY(osg::WARN) << "Less " #text " coordinates than vertices found. Skipping " #text " components." << std::endl; \ + arrayName = NULL; \ + } \ + } \ +/**/ + const bool readDoubleVertices = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0; + const bool readDoubleColors = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0; + const bool readDoubleNormals = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_NORMAL) != 0; + const bool readDoubleTexcoords = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0; + + unsigned int nbVertices(0); + // TODO Factorize code below! { - osg::Vec3Array* pArray = new osg::Vec3Array; - - for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), - end = vertexIndicesIndexMap.end(); it != end; ++it) + if (!readDoubleVertices) { - pArray->push_back(source->at(it->first.position_index)); + const osg::Vec3Array * source = sources[position_source].getVec3Array(); + if (source) + { + nbVertices = source->size(); + osg::Vec3Array* pArray = new osg::Vec3Array; + FOREACH_INDEX pArray->push_back(source->at(it->first.position_index)); + geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); + } + } + else + { + const osg::Vec3dArray* source = sources[position_source].getVec3dArray(); + if (source) + { + nbVertices = source->size(); + osg::Vec3dArray* pArray = new osg::Vec3dArray; + FOREACH_INDEX pArray->push_back(source->at(it->first.position_index)); + geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); + } } - - geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); } if (color_source) { - if (const osg::Vec4Array* source = sources[color_source].getVec4Array()) + if (!readDoubleColors) { - osg::Vec4Array* pArray = new osg::Vec4Array; - - for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), - end = vertexIndicesIndexMap.end(); it != end; ++it) + const osg::Vec4Array * colorSource = sources[color_source].getVec4Array(); + ENSURE_VECTOR_SIZE(colorSource, color) + if (colorSource) { - pArray->push_back(source->at(it->first.color_index)); + osg::Vec4Array* pArray = new osg::Vec4Array; + FOREACH_INDEX pArray->push_back(colorSource->at(it->first.color_index)); + geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); + } + } + else + { + const osg::Vec4dArray* colorSource = sources[color_source].getVec4dArray(); + ENSURE_VECTOR_SIZE(colorSource, color) + if (colorSource) + { + osg::Vec4dArray* pArray = new osg::Vec4dArray; + FOREACH_INDEX pArray->push_back(colorSource->at(it->first.color_index)); + geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); } - - geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); } } if (normal_source) { - if (const osg::Vec3Array* source = sources[normal_source].getVec3Array()) + if (!readDoubleNormals) { - osg::Vec3Array* pArray = new osg::Vec3Array; - - for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), - end = vertexIndicesIndexMap.end(); it != end; ++it) + const osg::Vec3Array * normalSource = sources[normal_source].getVec3Array(); + ENSURE_VECTOR_SIZE(normalSource, normal) + if (normalSource) { - pArray->push_back(source->at(it->first.normal_index)); + osg::Vec3Array* pArray = new osg::Vec3Array; + FOREACH_INDEX pArray->push_back(normalSource->at(it->first.normal_index)); + geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); + } + } + else + { + const osg::Vec3dArray* normalSource = sources[normal_source].getVec3dArray(); + ENSURE_VECTOR_SIZE(normalSource, normal) + if (normalSource) + { + osg::Vec3dArray* pArray = new osg::Vec3dArray; + FOREACH_INDEX pArray->push_back(normalSource->at(it->first.normal_index)); + geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); } - - geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); } } @@ -844,34 +895,59 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray, if (daeElement* texcoord_source = texcoord_sources[texcoord_set]) { osg::Array* pArray = NULL; - - if (const osg::Vec2Array* source = sources[texcoord_source].getVec2Array()) + if (!readDoubleTexcoords) { - osg::Vec2Array* pVec2Array = new osg::Vec2Array; - pArray = pVec2Array; - - for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), - end = vertexIndicesIndexMap.end(); it != end; ++it) + const osg::Vec2Array * tcSource2f = sources[texcoord_source].getVec2Array(); + const osg::Vec3Array * tcSource3f = sources[texcoord_source].getVec3Array(); + if (tcSource2f) { - pVec2Array->push_back(source->at(it->first.texcoord_indices[texcoord_set])); + ENSURE_VECTOR_SIZE(tcSource2f, texture) + if (tcSource2f) + { + osg::Vec2Array* pVec2Array = new osg::Vec2Array; + pArray = pVec2Array; + FOREACH_INDEX pVec2Array->push_back(tcSource2f->at(it->first.texcoord_indices[texcoord_set])); + } + } + else if (tcSource3f) + { + ENSURE_VECTOR_SIZE(tcSource3f, texture) + if (tcSource3f) { + osg::Vec3Array* pVec3Array = new osg::Vec3Array; + pArray = pVec3Array; + FOREACH_INDEX pVec3Array->push_back(tcSource3f->at(it->first.texcoord_indices[texcoord_set])); + } } } - else if (const osg::Vec3Array* source = sources[texcoord_source].getVec3Array()) + else { - osg::Vec3Array* pVec3Array = new osg::Vec3Array; - pArray = pVec3Array; - - for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), - end = vertexIndicesIndexMap.end(); it != end; ++it) + const osg::Vec2dArray* tcSource2d = sources[texcoord_source].getVec2dArray(); + const osg::Vec3dArray* tcSource3d = sources[texcoord_source].getVec3dArray(); + if (tcSource2d) { - pVec3Array->push_back(source->at(it->first.texcoord_indices[texcoord_set])); + ENSURE_VECTOR_SIZE(tcSource2d, texture) + if (tcSource2d) { + osg::Vec2dArray* pVec2Array = new osg::Vec2dArray; + pArray = pVec2Array; + FOREACH_INDEX pVec2Array->push_back(tcSource2d->at(it->first.texcoord_indices[texcoord_set])); + } + } + else if (tcSource3d) + { + ENSURE_VECTOR_SIZE(tcSource3d, texture) + if (tcSource3d) { + osg::Vec3dArray* pVec3Array = new osg::Vec3dArray; + pArray = pVec3Array; + FOREACH_INDEX pVec3Array->push_back(tcSource3d->at(it->first.texcoord_indices[texcoord_set])); + } } } - if (pArray) { geometry->setTexCoordData(texcoord_set, osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); } } } + +#undef FOREACH_INDEX } diff --git a/src/osgPlugins/dae/daeRSkinning.cpp b/src/osgPlugins/dae/daeRSkinning.cpp index f2ec22969..5ba0ed07e 100644 --- a/src/osgPlugins/dae/daeRSkinning.cpp +++ b/src/osgPlugins/dae/daeRSkinning.cpp @@ -360,18 +360,56 @@ void daeReader::processSkin(domSkin* pDomSkin, domNode* skeletonRoot, osgAnimati if (!pOsgRigGeometry) continue; - osg::Vec3Array& vertices = *static_cast(pOsgRigGeometry->getVertexArray()); - - for (size_t i = 0; i < vertices.size(); ++i) + osg::Array * vert = pOsgRigGeometry->getVertexArray(); + osg::Vec3Array * vertf = NULL; + osg::Vec3dArray* vertd = NULL; + if (vert->getType() == osg::Array::Vec3ArrayType) { - vertices[i] = vertices[i] * bindMatrix; + vertf = static_cast(vert); + for (size_t i = 0; i < vertf->size(); ++i) + { + (*vertf)[i] = (*vertf)[i] * bindMatrix; + } + } + else if (vert->getType() == osg::Array::Vec3dArrayType) + { + vertd = static_cast(vert); + for (size_t i = 0; i < vertd->size(); ++i) + { + (*vertd)[i] = (*vertd)[i] * bindMatrix; + } + } + else + { + OSG_NOTIFY(osg::WARN) << "Vertices vector type isn't supported." << std::endl; + continue; } - if (osg::Vec3Array* normals = static_cast(pOsgRigGeometry->getNormalArray())) + osg::Array * norm = pOsgRigGeometry->getNormalArray(); + if (norm) { - for (size_t i = 0; i < normals->size(); ++i) + osg::Vec3Array * normf = NULL; + osg::Vec3dArray* normd = NULL; + if (norm->getType() == osg::Array::Vec3ArrayType) { - (*normals)[i] = osg::Matrix::transform3x3((*normals)[i], bindMatrix); + normf = static_cast(norm); + for (size_t i = 0; i < normf->size(); ++i) + { + (*normf)[i] = osg::Matrix::transform3x3((*normf)[i], bindMatrix); + } + } + else if (norm->getType() == osg::Array::Vec3dArrayType) + { + normd = static_cast(norm); + for (size_t i = 0; i < normd->size(); ++i) + { + (*normd)[i] = osg::Matrix::transform3x3((*normd)[i], bindMatrix); + } + } + else + { + OSG_NOTIFY(osg::WARN) << "Normals vector type isn't supported." << std::endl; + //continue; } } diff --git a/src/osgPlugins/dae/daeReader.cpp b/src/osgPlugins/dae/daeReader.cpp index e3226a3f0..f7b463ffa 100644 --- a/src/osgPlugins/dae/daeReader.cpp +++ b/src/osgPlugins/dae/daeReader.cpp @@ -22,7 +22,7 @@ using namespace osgDAE; -daeReader::daeReader(DAE *dae_, bool strictTransparency) : +daeReader::daeReader(DAE *dae_, bool strictTransparency, int precisionHint) : _dae(dae_), _rootNode(NULL), _visualScene(NULL), @@ -32,6 +32,7 @@ daeReader::daeReader(DAE *dae_, bool strictTransparency) : _authoringTool(UNKNOWN), _strictTransparency(strictTransparency), _invertTransparency(false), + _precisionHint(precisionHint), _assetUnitName("meter"), _assetUnitMeter(1.0), _assetUp_axis(UPAXISTYPE_Y_UP) diff --git a/src/osgPlugins/dae/daeReader.h b/src/osgPlugins/dae/daeReader.h index 7d008e7c5..d342cbc85 100644 --- a/src/osgPlugins/dae/daeReader.h +++ b/src/osgPlugins/dae/daeReader.h @@ -133,7 +133,7 @@ inline osg::Matrix parseMatrixString(const std::string& valueAsString) */ class daeReader { public: - daeReader(DAE *dae_, bool strictTransparency = false); + daeReader(DAE *dae_, bool strictTransparency, int precisionHint); virtual ~daeReader(); bool convert( const std::string &fileURI ); @@ -393,6 +393,7 @@ private: AuthoringTool _authoringTool; bool _strictTransparency, _invertTransparency; + int _precisionHint; ///< Precision hint flags, as specified in osgDB::Options::PrecisionHint // Additional Information std::string _assetUnitName; diff --git a/src/osgPlugins/dae/daeWGeometry.cpp b/src/osgPlugins/dae/daeWGeometry.cpp index eafde1809..39145792f 100644 --- a/src/osgPlugins/dae/daeWGeometry.cpp +++ b/src/osgPlugins/dae/daeWGeometry.cpp @@ -26,6 +26,70 @@ using namespace osgDAE; + +unsigned int daeWriter::ArrayNIndices::getDAESize() +{ + switch( mode ) + { + case VEC2F: + case VEC2D: + return 2; + case VEC3F: + case VEC3D: + return 3; + case VEC4F: + case VEC4D: + case VEC4_UB: + return 4; + case NONE: + return 0; + } + return 0; +} + +/// Appends an OSG vector (Vec2, Vec3...) to a domListOfFloats. +template +inline void append(domListOfFloats & list, const VecType & vec) +{ + for(unsigned int i=0; ibegin(), itEnd=vec2->end(); it!=itEnd; ++it) ::append(list, *it); + break; + case VEC2D: + for (osg::Vec2dArray::const_iterator it=vec2d->begin(), itEnd=vec2d->end(); it!=itEnd; ++it) ::append(list, *it); + break; + case VEC3F: + for (osg::Vec3Array::const_iterator it=vec3->begin(), itEnd=vec3->end(); it!=itEnd; ++it) ::append(list, *it); + break; + case VEC3D: + for (osg::Vec3dArray::const_iterator it=vec3d->begin(), itEnd=vec3d->end(); it!=itEnd; ++it) ::append(list, *it); + break; + case VEC4F: + for (osg::Vec4Array::const_iterator it=vec4->begin(), itEnd=vec4->end(); it!=itEnd; ++it) ::append(list, *it); + break; + case VEC4D: + for (osg::Vec4dArray::const_iterator it=vec4d->begin(), itEnd=vec4d->end(); it!=itEnd; ++it) ::append(list, *it); + break; + case VEC4_UB: + for (osg::Vec4ubArray::const_iterator it=vec4ub->begin(), itEnd=vec4ub->end(); it!=itEnd; ++it) ::append(list, *it); + break; + default: + return false; + } + return true; +} + + + + + domGeometry* daeWriter::getOrCreateDomGeometry(osg::Geometry* pOsgGeometry) { // See if geometry exists in cache @@ -42,7 +106,7 @@ domGeometry* daeWriter::getOrCreateDomGeometry(osg::Geometry* pOsgGeometry) } domGeometry* pDomGeometry = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) ); - std::string name = pOsgGeometry->getName(); + std::string name( pOsgGeometry->getName() ); if (name.empty()) name = uniquify("geometry"); else @@ -89,7 +153,7 @@ void daeWriter::writeRigGeometry(osgAnimation::RigGeometry *pOsgRigGeometry) // 1 // 0..1 pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) ); - std::string name = pOsgRigGeometry->getName(); + std::string name( pOsgRigGeometry->getName() ); if (name.empty()) name = uniquify("skincontroller"); else @@ -257,7 +321,7 @@ void daeWriter::writeMorphGeometry(osgAnimation::MorphGeometry *pOsgMorphGeometr // 0..* // 0..* pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) ); - std::string name = pOsgMorphGeometry->getName(); + std::string name( pOsgMorphGeometry->getName() ); if (name.empty()) name = uniquify("morphcontroller"); else @@ -364,6 +428,7 @@ void daeWriter::writeMorphGeometry(osgAnimation::MorphGeometry *pOsgMorphGeometr void daeWriter::apply( osg::Geode &node ) { debugPrint( node ); + updateCurrentDaeNode(); pushStateSet(node.getStateSet()); if (NULL != node.getStateSet()) @@ -465,10 +530,10 @@ void daeWriter::appendGeometryIndices(osg::Geometry *geom, //ArrayNIndices &tc = texcoords[ti]; p->getValue().append( texcoords[ti].inds!=NULL?texcoords[ti].inds->index(vindex):vindex ); } - } - + + bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const std::string &name ) { domMesh *mesh = daeSafeCast< domMesh >( geo->add( COLLADA_ELEMENT_MESH ) ); @@ -508,104 +573,45 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st vertexAttributes.push_back(ArrayNIndices( geom->getVertexAttribArray( i ), geom->getVertexAttribIndices(i))); } } - - // process POSITION - std::string sName = name + "-positions"; - pos = createSource( mesh, sName, verts.mode ); - switch( verts.mode ) + // process POSITION + std::string sName; { - case ArrayNIndices::VEC2: - pos->getFloat_array()->setCount( verts.vec2->size() *2 ); - pos->getTechnique_common()->getAccessor()->setCount( verts.vec2->size() ); - for ( unsigned int i = 0; i < verts.vec2->size(); i++ ) + sName = name + "-positions"; + unsigned int elementSize = verts.getDAESize(); + unsigned int numElements = verts.valArray->getNumElements(); + pos = createSource( mesh, sName, elementSize ); + pos->getFloat_array()->setCount( numElements * elementSize ); + pos->getTechnique_common()->getAccessor()->setCount( numElements ); + if (!verts.append(pos->getFloat_array()->getValue())) { - pos->getFloat_array()->getValue().append( (*verts.vec2)[i].x() ); - pos->getFloat_array()->getValue().append( (*verts.vec2)[i].y() ); + OSG_WARN << "Invalid array type for vertices" << std::endl; } - break; - case ArrayNIndices::VEC3: - pos->getFloat_array()->setCount( verts.vec3->size() *3 ); - pos->getTechnique_common()->getAccessor()->setCount( verts.vec3->size() ); - for ( unsigned int i = 0; i < verts.vec3->size(); i++ ) - { - pos->getFloat_array()->getValue().append( (*verts.vec3)[i].x() ); - pos->getFloat_array()->getValue().append( (*verts.vec3)[i].y() ); - pos->getFloat_array()->getValue().append( (*verts.vec3)[i].z() ); - } - break; - case ArrayNIndices::VEC4: - pos->getFloat_array()->setCount( verts.vec4->size() *4 ); - pos->getTechnique_common()->getAccessor()->setCount( verts.vec4->size() ); - for ( unsigned int i = 0; i < verts.vec4->size(); i++ ) - { - pos->getFloat_array()->getValue().append( (*verts.vec4)[i].x() ); - pos->getFloat_array()->getValue().append( (*verts.vec4)[i].y() ); - pos->getFloat_array()->getValue().append( (*verts.vec4)[i].z() ); - pos->getFloat_array()->getValue().append( (*verts.vec4)[i].w() ); - } - break; - default: - OSG_WARN << "Invalid array type for vertices" << std::endl; - break; + + //create a vertices element + domVertices *vertices = daeSafeCast< domVertices >( mesh->add( COLLADA_ELEMENT_VERTICES ) ); + std::string vName = name + "-vertices"; + vertices->setId( vName.c_str() ); + + //make a POSITION input in it + domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); + il->setSemantic( COMMON_PROFILE_INPUT_POSITION ); + std::string url("#" + std::string(pos->getId()) ); + il->setSource( url.c_str() ); } - //create a vertices element - domVertices *vertices = daeSafeCast< domVertices >( mesh->add( COLLADA_ELEMENT_VERTICES ) ); - std::string vName = name + "-vertices"; - vertices->setId( vName.c_str() ); - - //make a POSITION input in it - domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); - il->setSemantic( COMMON_PROFILE_INPUT_POSITION ); - std::string url = "#" + std::string( pos->getId() ); - il->setSource( url.c_str() ); - //process NORMAL - if ( normals.mode != ArrayNIndices::NONE ) + if ( normals.getMode() != ArrayNIndices::NONE ) { sName = name + "-normals"; - norm = createSource( mesh, sName, normals.mode ); - - switch( normals.mode ) + unsigned int elementSize = normals.getDAESize(); + unsigned int numElements = normals.valArray->getNumElements(); + norm = createSource( mesh, sName, elementSize ); + norm->getFloat_array()->setCount( numElements * elementSize ); + norm->getTechnique_common()->getAccessor()->setCount( numElements ); + if (!normals.append(norm->getFloat_array()->getValue())) { - case ArrayNIndices::VEC2: - norm->getFloat_array()->setCount( normals.vec2->size() *2 ); - norm->getTechnique_common()->getAccessor()->setCount( normals.vec2->size() ); - for ( unsigned int i = 0; i < normals.vec2->size(); i++ ) - { - norm->getFloat_array()->getValue().append( (*normals.vec2)[i].x() ); - norm->getFloat_array()->getValue().append( (*normals.vec2)[i].y() ); - } - break; - case ArrayNIndices::VEC3: - norm->getFloat_array()->setCount( normals.vec3->size() *3 ); - norm->getTechnique_common()->getAccessor()->setCount( normals.vec3->size() ); - for ( unsigned int i = 0; i < normals.vec3->size(); i++ ) - { - norm->getFloat_array()->getValue().append( (*normals.vec3)[i].x() ); - norm->getFloat_array()->getValue().append( (*normals.vec3)[i].y() ); - norm->getFloat_array()->getValue().append( (*normals.vec3)[i].z() ); - } - break; - case ArrayNIndices::VEC4: - norm->getFloat_array()->setCount( normals.vec4->size() *4 ); - norm->getTechnique_common()->getAccessor()->setCount( normals.vec4->size() ); - for ( unsigned int i = 0; i < normals.vec4->size(); i++ ) - { - norm->getFloat_array()->getValue().append( (*normals.vec4)[i].x() ); - norm->getFloat_array()->getValue().append( (*normals.vec4)[i].y() ); - norm->getFloat_array()->getValue().append( (*normals.vec4)[i].z() ); - norm->getFloat_array()->getValue().append( (*normals.vec4)[i].w() ); - } - break; - - //no normals - case ArrayNIndices::NONE: - OSG_WARN << "No array type for normals"<getNumElements(); + color = createSource( mesh, sName, elementSize, true ); + color->getFloat_array()->setCount( numElements * elementSize ); + color->getTechnique_common()->getAccessor()->setCount( numElements ); + if (!colors.append(color->getFloat_array()->getValue())) { - case ArrayNIndices::VEC2: - color->getFloat_array()->setCount( colors.vec2->size() *2 ); - color->getTechnique_common()->getAccessor()->setCount( colors.vec2->size() ); - for ( unsigned int i = 0; i < colors.vec2->size(); i++ ) - { - color->getFloat_array()->getValue().append( (*colors.vec2)[i].x() ); - color->getFloat_array()->getValue().append( (*colors.vec2)[i].y() ); - } - break; - case ArrayNIndices::VEC3: - color->getFloat_array()->setCount( colors.vec3->size() *3 ); - color->getTechnique_common()->getAccessor()->setCount( colors.vec3->size() ); - for ( unsigned int i = 0; i < colors.vec3->size(); i++ ) - { - color->getFloat_array()->getValue().append( (*colors.vec3)[i].x() ); - color->getFloat_array()->getValue().append( (*colors.vec3)[i].y() ); - color->getFloat_array()->getValue().append( (*colors.vec3)[i].z() ); - } - break; - case ArrayNIndices::VEC4: - color->getFloat_array()->setCount( colors.vec4->size() *4 ); - color->getTechnique_common()->getAccessor()->setCount( colors.vec4->size() ); - for ( unsigned int i = 0; i < colors.vec4->size(); i++ ) - { - color->getFloat_array()->getValue().append( (*colors.vec4)[i].r() ); - color->getFloat_array()->getValue().append( (*colors.vec4)[i].g() ); - color->getFloat_array()->getValue().append( (*colors.vec4)[i].b() ); - color->getFloat_array()->getValue().append( (*colors.vec4)[i].a() ); - } - break; - default: OSG_WARN << "Invalid array type for colors" << std::endl; - break; } + //if COLOR shares same indices as POSITION put it in the vertices /*if ( colorInds == vertInds && vertInds != NULL ) { il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); @@ -672,106 +650,47 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many for ( unsigned int ti = 0; ti < texcoords.size(); ti++ ) { + if (texcoords[ti].getMode() == ArrayNIndices::NONE) continue; + std::ostringstream intstr; intstr << std::dec << ti; sName = name + "-texcoord_" + intstr.str(); - domSource *t = createSource( mesh, sName, texcoords[ti].mode, false, true ); - switch( texcoords[ti].mode ) + unsigned int elementSize = texcoords[ti].getDAESize(); + unsigned int numElements = texcoords[ti].valArray->getNumElements(); + domSource *t = createSource( mesh, sName, elementSize, false, true ); + t->getFloat_array()->setCount( numElements * elementSize ); + t->getTechnique_common()->getAccessor()->setCount( numElements ); + if (!texcoords[ti].append(t->getFloat_array()->getValue())) { - case ArrayNIndices::VEC2: - t->getFloat_array()->setCount( texcoords[ti].vec2->size() *2 ); - t->getTechnique_common()->getAccessor()->setCount( texcoords[ti].vec2->size() ); - for ( unsigned int i = 0; i < texcoords[ti].vec2->size(); i++ ) - { - t->getFloat_array()->getValue().append( (*texcoords[ti].vec2)[i].x() ); - t->getFloat_array()->getValue().append( (*texcoords[ti].vec2)[i].y() ); - } - break; - case ArrayNIndices::VEC3: - t->getFloat_array()->setCount( texcoords[ti].vec3->size() *3 ); - t->getTechnique_common()->getAccessor()->setCount( texcoords[ti].vec3->size() ); - for ( unsigned int i = 0; i < texcoords[ti].vec3->size(); i++ ) - { - t->getFloat_array()->getValue().append( (*texcoords[ti].vec3)[i].x() ); - t->getFloat_array()->getValue().append( (*texcoords[ti].vec3)[i].y() ); - t->getFloat_array()->getValue().append( (*texcoords[ti].vec3)[i].z() ); - } - break; - case ArrayNIndices::VEC4: - t->getFloat_array()->setCount( texcoords[ti].vec4->size() *4 ); - t->getTechnique_common()->getAccessor()->setCount( texcoords[ti].vec4->size() ); - for ( unsigned int i = 0; i < texcoords[ti].vec4->size(); i++ ) - { - t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].x() ); - t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].y() ); - t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].z() ); - t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].w() ); - } - break; - default: - //##ti and not i - OSG_WARN << "Invalid array type for texcoord" << ti << std::endl; - break; + OSG_WARN << "Invalid array type for texcoord" << std::endl; } + texcoord.push_back( t ); } //RS - //process TEXCOORD + //process VERTEX ATTRIBUTES //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many for ( unsigned int ti = 0; ti < vertexAttributes.size(); ti++ ) { - if (vertexAttributes[ti].mode != ArrayNIndices::NONE) - { - std::ostringstream intstr; - intstr << std::dec << ti; - sName = name + "-vertexAttribute_" + intstr.str(); + if (vertexAttributes[ti].getMode() == ArrayNIndices::NONE) continue; - domSource *t = createSource( mesh, sName, vertexAttributes[ti].mode, false, true ); - switch( vertexAttributes[ti].mode ) - { - case ArrayNIndices::VEC2: - t->getFloat_array()->setCount( vertexAttributes[ti].vec2->size() *2 ); - t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec2->size() ); - for ( unsigned int i = 0; i < vertexAttributes[ti].vec2->size(); i++ ) - { - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec2)[i].x() ); - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec2)[i].y() ); - } - break; - case ArrayNIndices::VEC3: - t->getFloat_array()->setCount( vertexAttributes[ti].vec3->size() *3 ); - t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec3->size() ); - for ( unsigned int i = 0; i < vertexAttributes[ti].vec3->size(); i++ ) - { - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].x() ); - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].y() ); - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].z() ); - } - break; - case ArrayNIndices::VEC4: - t->getFloat_array()->setCount( vertexAttributes[ti].vec4->size() *4 ); - t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec4->size() ); - for ( unsigned int i = 0; i < vertexAttributes[ti].vec4->size(); i++ ) - { - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].x() ); - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].y() ); - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].z() ); - t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].w() ); - } - break; - default: - //##ti and not i - OSG_WARN << "Invalid array type for vertex attribute" << ti << std::endl; - break; - } - vertexAttribute.push_back( t ); - } - else + std::ostringstream intstr; + intstr << std::dec << ti; + sName = name + "-vertexAttribute_" + intstr.str(); + + unsigned int elementSize = vertexAttributes[ti].getDAESize(); + unsigned int numElements = vertexAttributes[ti].valArray->getNumElements(); + domSource *t = createSource( mesh, sName, elementSize, false, true ); // Sukender: should we *REALLY* call createSource(... false, true)? (I mean with such flags) + t->getFloat_array()->setCount( numElements * elementSize ); + t->getTechnique_common()->getAccessor()->setCount( numElements ); + if (!vertexAttributes[ti].append(t->getFloat_array()->getValue())) { OSG_WARN << "Invalid array type for vertex attribute" << ti << std::endl; } + + vertexAttribute.push_back( t ); } //process each primitive group @@ -1001,7 +920,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st verts,normals,colors,texcoords, ncount,ccount); - if ( vcount % primLength == 0 ) + if ( vcount>0 && ((vcount % primLength) == 0) ) { if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) { @@ -1092,30 +1011,30 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st unsigned int indexEnd=indexBegin+nbVerticesPerPoly; for( unsigned int iPoly = 0; iPoly < p.size(); ++iPoly ) { - // printf("indexBegin %d,indexPolyEnd %d \n",indexBegin,indexEnd); - for( unsigned int primCount = indexBegin; primCount < indexEnd; ++primCount ) + // printf("indexBegin %d,indexPolyEnd %d \n",indexBegin,indexEnd); + for( unsigned int primCount = indexBegin; primCount < indexEnd; ++primCount ) { - appendGeometryIndices(geom,p[iPoly],vindex, - norm,color, - verts,normals,colors,texcoords, - ncount,ccount); - - if ( primCount % localPrimLength == 0 ) - { - if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) - { + appendGeometryIndices(geom,p[iPoly],vindex, + norm,color, + verts,normals,colors,texcoords, + ncount,ccount); + + if ( primCount>0 && ((primCount % localPrimLength) == 0) ) + { + if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) + { ncount++; - } - if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) - { + } + if ( geom->getColorBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) + { ccount++; - } - } - vindex++; - } - indexBegin+=nbVerticesPerPoly; - indexEnd+=nbVerticesPerPoly; - } + } + } + vindex++; + } + indexBegin+=nbVerticesPerPoly; + indexEnd+=nbVerticesPerPoly; + } } break; } @@ -1194,13 +1113,13 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st { unsigned int vindex = *primItr; - + appendGeometryIndices(geom,p[iPoly],vindex, norm,color, verts,normals,colors,texcoords, ncount,ccount); - - if ( primCount % primLength == 0 ) + + if ( primCount>0 && ((primCount % primLength) == 0) ) { if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) { @@ -1299,7 +1218,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st verts,normals,colors,texcoords, ncount,ccount); - if ( primCount % primLength == 0 ) + if ( primCount>0 && ((primCount % primLength) == 0) ) { if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) { @@ -1401,7 +1320,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st verts,normals,colors,texcoords, ncount,ccount); - if ( primCount % primLength == 0 ) + if ( primCount>0 && ((primCount % primLength) == 0) ) { if ( geom->getNormalBinding() == osg::Geometry::BIND_PER_PRIMITIVE ) { @@ -1471,7 +1390,8 @@ domSource *daeWriter::createSource( daeElement *parent, const std::string &baseN param->setName( "B" ); param->setType( "float" ); - if ( size == 4 ) { + if ( size == 4 ) + { param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "A" ); param->setType( "float" ); @@ -1480,44 +1400,47 @@ domSource *daeWriter::createSource( daeElement *parent, const std::string &baseN } else if ( uv ) { + const char * const type = "float"; + acc->setStride( size ); param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "S" ); - param->setType( "float" ); + param->setType( type ); param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "T" ); - param->setType( "float" ); + param->setType( type ); if ( size >=3 ) { param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "P" ); - param->setType( "float" ); + param->setType( type ); } } else { + const char * const type = "float"; acc->setStride( size ); param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "X" ); - param->setType( "float" ); + param->setType( type ); param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "Y" ); - param->setType( "float" ); + param->setType( type ); if ( size >=3 ) { param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "Z" ); - param->setType( "float" ); + param->setType( type ); if ( size == 4 ) { param = daeSafeCast< domParam >( acc->add( COLLADA_ELEMENT_PARAM ) ); param->setName( "W" ); - param->setType( "float" ); + param->setType( type ); } } } diff --git a/src/osgPlugins/dae/daeWriter.cpp b/src/osgPlugins/dae/daeWriter.cpp index 96e3f644c..5c6092266 100644 --- a/src/osgPlugins/dae/daeWriter.cpp +++ b/src/osgPlugins/dae/daeWriter.cpp @@ -23,6 +23,53 @@ namespace osgDAE { +daeWriter::ArrayNIndices::ArrayNIndices( osg::Array* valArray, osg::IndexArray* ind ) : + vec2(0), vec3(0), vec4(0), + vec2d(0), vec3d(0), vec4d(0), + vec4ub(0), + valArray(valArray), + inds( ind ), mode(NONE) +{ + if ( valArray != NULL ) + { + switch( valArray->getType() ) + { + case osg::Array::Vec2ArrayType: + mode = VEC2F; + vec2 = (osg::Vec2Array*)valArray; + break; + case osg::Array::Vec3ArrayType: + mode = VEC3F; + vec3 = (osg::Vec3Array*)valArray; + break; + case osg::Array::Vec4ArrayType: + mode = VEC4F; + vec4 = (osg::Vec4Array*)valArray; + break; + case osg::Array::Vec2dArrayType: + mode = VEC2D; + vec2d = (osg::Vec2dArray*)valArray; + break; + case osg::Array::Vec3dArrayType: + mode = VEC3D; + vec3d = (osg::Vec3dArray*)valArray; + break; + case osg::Array::Vec4dArrayType: + mode = VEC4D; + vec4d = (osg::Vec4dArray*)valArray; + break; + case osg::Array::Vec4ubArrayType: + mode = VEC4_UB; + vec4ub = (osg::Vec4ubArray*)valArray; + break; + default: + OSG_WARN << "Array is unsupported vector type" << std::endl; + break; + } + } +} + + std::string toString(const osg::Vec3f& value) { std::stringstream str; diff --git a/src/osgPlugins/dae/daeWriter.h b/src/osgPlugins/dae/daeWriter.h index dc71cfd04..1bbab37e8 100644 --- a/src/osgPlugins/dae/daeWriter.h +++ b/src/osgPlugins/dae/daeWriter.h @@ -71,7 +71,8 @@ namespace osgDAE { /// Convert value to string using it's stream operator template -std::string toString(T value) { +std::string toString(T value) +{ std::stringstream str; str << value; return str.str(); @@ -254,37 +255,29 @@ protected: //inner classes class ArrayNIndices { public: - enum Mode { NONE = 0, VEC2 = 2, VEC3 = 3, VEC4 = 4 }; - osg::Vec2Array* vec2; - osg::Vec3Array* vec3; - osg::Vec4Array* vec4; - osg::IndexArray* inds; - Mode mode; + enum Mode { NONE, VEC2F, VEC2D, VEC3F, VEC3D, VEC4F, VEC4D, VEC4_UB }; - ArrayNIndices( osg::Array *array, osg::IndexArray *ind ) : vec2(0), vec3(0), vec4(0), inds( ind ), mode(NONE) - { - if ( array != NULL ) - { - switch( array->getType() ) - { - case osg::Array::Vec2ArrayType: - mode = VEC2; - vec2 = (osg::Vec2Array*)array; - break; - case osg::Array::Vec3ArrayType: - mode = VEC3; - vec3 = (osg::Vec3Array*)array; - break; - case osg::Array::Vec4ArrayType: - mode = VEC4; - vec4 = (osg::Vec4Array*)array; - break; - default: - OSG_WARN << "Array is unsupported vector type" << std::endl; - break; - } - } - } + osg::Vec2Array* vec2; + osg::Vec3Array* vec3; + osg::Vec4Array* vec4; + osg::Vec2dArray* vec2d; + osg::Vec3dArray* vec3d; + osg::Vec4dArray* vec4d; + osg::Vec4ubArray* vec4ub; + + osg::Array* valArray; + osg::IndexArray* inds; + + ArrayNIndices( osg::Array* valArray, osg::IndexArray* ind ); + + Mode getMode() const { return mode; } + + unsigned int getDAESize(); + + /// Appends the contained OSG vector array to a domListOfFloats + bool append(domListOfFloats & list); + protected: + Mode mode; }; private: //members diff --git a/src/osgPlugins/dae/domSourceReader.cpp b/src/osgPlugins/dae/domSourceReader.cpp index d0cb4d86d..b9133aa1a 100644 --- a/src/osgPlugins/dae/domSourceReader.cpp +++ b/src/osgPlugins/dae/domSourceReader.cpp @@ -17,13 +17,20 @@ using namespace osgDAE; -domSourceReader::domSourceReader() : m_array_type( None ), m_count( 0 ) +domSourceReader::domSourceReader() : m_array_type( None ), m_count( 0 ), srcInit( NULL )//, initialized( false ) {} -domSourceReader::domSourceReader( domSource *src ) : m_array_type( None ), m_count( 0 ) +domSourceReader::domSourceReader( domSource *src ) : m_array_type( None ), m_count( 0 ), srcInit( src )//, initialized( false ) { +} + +void domSourceReader::convert(bool doublePrecision) +{ + domSource * src = srcInit; + srcInit = NULL; domSource::domTechnique_common* technique = src->getTechnique_common(); - if ( technique == NULL ) { + if ( technique == NULL ) + { OSG_WARN<<"Warning: IntDaeSource::createFrom: Unable to find COMMON technique"<getCount(); i++ ) + switch (m_array_type) { - switch ( accessor->getStride() ) - { - case 1: - m_float_array->push_back(va[i]); - break; - case 2: - m_vec2_array->push_back( osg::Vec2( va[i*2], va[i*2+1])); - break; - case 3: - m_vec3_array->push_back( osg::Vec3( va[i*3], va[i*3+1], va[i*3+2])); - break; - case 4: - m_vec4_array->push_back( osg::Vec4( va[i*4], va[i*4+1], va[i*4+2], va[i*4+3])); - break; - case 16: - m_matrix_array->push_back(osg::Matrixf( va[i*16+0], va[i*16+4], va[i*16+8], va[i*16+12], - va[i*16+1], va[i*16+5], va[i*16+9], va[i*16+13], - va[i*16+2], va[i*16+6], va[i*16+10], va[i*16+14], - va[i*16+3], va[i*16+7], va[i*16+11], va[i*16+15])); - break; - default: - OSG_WARN << "Unsupported stride in Source: " << accessor->getStride() << std::endl; - return; + case Float: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_float_array->push_back(va[i]); } + break; + case Vec2: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_vec2_array->push_back( osg::Vec2( va[i*2], va[i*2+1])); + } + break; + case Vec2d: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_vec2d_array->push_back( osg::Vec2d( va[i*2], va[i*2+1])); + } + break; + case Vec3: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_vec3_array->push_back( osg::Vec3( va[i*3], va[i*3+1], va[i*3+2])); + } + break; + case Vec3d: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_vec3d_array->push_back( osg::Vec3d( va[i*3], va[i*3+1], va[i*3+2])); + } + break; + case Vec4: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_vec4_array->push_back( osg::Vec4( va[i*4], va[i*4+1], va[i*4+2], va[i*4+3])); + } + break; + case Vec4d: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_vec4d_array->push_back( osg::Vec4d( va[i*4], va[i*4+1], va[i*4+2], va[i*4+3])); + } + break; + case Matrix: + for ( size_t i = 0; i < accessor->getCount(); i++ ) { + m_matrix_array->push_back(osg::Matrixf( va[i*16+0], va[i*16+4], va[i*16+8], va[i*16+12], + va[i*16+1], va[i*16+5], va[i*16+9], va[i*16+13], + va[i*16+2], va[i*16+6], va[i*16+10], va[i*16+14], + va[i*16+3], va[i*16+7], va[i*16+11], va[i*16+15])); + } + break; + default: + OSG_WARN << "Unsupported stride in Source: " << stride << std::endl; + return; } } else diff --git a/src/osgPlugins/dae/domSourceReader.h b/src/osgPlugins/dae/domSourceReader.h index 2ee62d92a..02f212837 100644 --- a/src/osgPlugins/dae/domSourceReader.h +++ b/src/osgPlugins/dae/domSourceReader.h @@ -23,31 +23,38 @@ namespace osgDAE { /** @class domSourceReader +Converts a source to an OSG vector array as soon as you call a getter, so calling simple precision version \c getVec3Array() will force getVec3dArray() to return NULL, and vice-versa (for a Vec3 array in the example). @brief Convert sources from DAE to OSG arrays */ class domSourceReader { public: - enum ArrayType {None,Float,Vec2,Vec3,Vec4,Matrix,String}; + enum ArrayType {None,Float,Vec2,Vec3,Vec4,Vec2d,Vec3d,Vec4d,Matrix,String}; public: domSourceReader(); - domSourceReader( domSource *src ); + explicit domSourceReader( domSource *src ); - ArrayType getArrayType() const { return m_array_type; }; + ArrayType getArrayType(bool enableDoublePrecision) const { if (srcInit) const_cast(this)->convert(enableDoublePrecision); return m_array_type; }; - osg::FloatArray* getFloatArray() { return m_float_array.get(); }; + osg::FloatArray* getFloatArray() { if (srcInit) convert(false); return m_float_array.get(); }; - osg::Vec2Array* getVec2Array() { return m_vec2_array.get(); }; + osg::Vec2Array* getVec2Array() { if (srcInit) convert(false); return m_vec2_array.get(); }; - osg::Vec3Array* getVec3Array() { return m_vec3_array.get(); }; + osg::Vec3Array* getVec3Array() { if (srcInit) convert(false); return m_vec3_array.get(); }; - osg::Vec4Array* getVec4Array() { return m_vec4_array.get(); }; - - osg::MatrixfArray* getMatrixArray() { return m_matrix_array.get(); }; - - int getCount() const { return m_count; }; + osg::Vec4Array* getVec4Array() { if (srcInit) convert(false); return m_vec4_array.get(); }; + + osg::Vec2dArray* getVec2dArray() { if (srcInit) convert(true); return m_vec2d_array.get(); }; + + osg::Vec3dArray* getVec3dArray() { if (srcInit) convert(true); return m_vec3d_array.get(); }; + + osg::Vec4dArray* getVec4dArray() { if (srcInit) convert(true); return m_vec4d_array.get(); }; + + osg::MatrixfArray* getMatrixArray() { if (srcInit) convert(false); return m_matrix_array.get(); }; + + int getCount(bool enableDoublePrecision) const { if (srcInit) const_cast(this)->convert(enableDoublePrecision); return m_count; }; #define ASSERT_TYPE(type) if (type!=m_array_type) { OSG_WARN<<"Wrong array type requested ("#type" != "< m_float_array; osg::ref_ptr m_vec2_array; osg::ref_ptr m_vec3_array; osg::ref_ptr m_vec4_array; + osg::ref_ptr m_vec2d_array; + osg::ref_ptr m_vec3d_array; + osg::ref_ptr m_vec4d_array; osg::ref_ptr m_matrix_array; };