From 8e53cfe6fc880af7c4e775ff31b22c4661da4879 Mon Sep 17 00:00:00 2001 From: Michael PLATINGS Date: Tue, 13 Apr 2010 14:50:31 +0000 Subject: [PATCH] Added support for double precision geometry --- src/osgPlugins/fbx/ReaderWriterFBX.cpp | 2 +- src/osgPlugins/fbx/WriterCompareTriangle.cpp | 224 +++++++++---------- src/osgPlugins/fbx/WriterCompareTriangle.h | 60 ++--- src/osgPlugins/fbx/fbxRMesh.cpp | 183 ++++++++++----- src/osgPlugins/fbx/fbxRMesh.h | 3 +- src/osgPlugins/fbx/fbxRNode.cpp | 4 +- src/osgPlugins/fbx/fbxRNode.h | 2 +- 7 files changed, 270 insertions(+), 208 deletions(-) diff --git a/src/osgPlugins/fbx/ReaderWriterFBX.cpp b/src/osgPlugins/fbx/ReaderWriterFBX.cpp index 2f434bddb..a484eeee8 100644 --- a/src/osgPlugins/fbx/ReaderWriterFBX.cpp +++ b/src/osgPlugins/fbx/ReaderWriterFBX.cpp @@ -293,7 +293,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, std::map skeletonMap; ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager, bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap, - boneBindMatrices, fbxSkeletons, skeletonMap, localOptions.get()); + boneBindMatrices, fbxSkeletons, skeletonMap, *localOptions); if (res.success()) { diff --git a/src/osgPlugins/fbx/WriterCompareTriangle.cpp b/src/osgPlugins/fbx/WriterCompareTriangle.cpp index ec69a5a70..bb202df4b 100644 --- a/src/osgPlugins/fbx/WriterCompareTriangle.cpp +++ b/src/osgPlugins/fbx/WriterCompareTriangle.cpp @@ -1,150 +1,150 @@ #include "WriterCompareTriangle.h" -WriterCompareTriangle::WriterCompareTriangle(const osg::Geode & geode, - unsigned int nbVertices) - : geode(geode) +WriterCompareTriangle::WriterCompareTriangle(const osg::Geode& geode, + unsigned int nbVertices) + : geode(geode) { - cutscene(nbVertices, geode.getDrawable ( 0 )->asGeometry()->getBound()); + cutscene(nbVertices, geode.getDrawable(0)->asGeometry()->getBound()); } bool -WriterCompareTriangle::operator()(const std::pair & t1, - const std::pair & t2) const +WriterCompareTriangle::operator()(const std::pair& t1, + const std::pair& t2) const { - const osg::Geometry *g = geode.getDrawable( t1.second )->asGeometry(); + const osg::Geometry* g = geode.getDrawable( t1.second )->asGeometry(); - const osg::Vec3Array * vecs= static_cast(g->getVertexArray()); - const osg::Vec3::value_type x1 = (*vecs)[t1.first.t1].x(); - const osg::Vec3::value_type y1 = (*vecs)[t1.first.t1].y(); - const osg::Vec3::value_type z1 = (*vecs)[t1.first.t1].z(); + const osg::Vec3Array* vecs= static_cast(g->getVertexArray()); + const osg::Vec3::value_type x1 = (*vecs)[t1.first.t1].x(); + const osg::Vec3::value_type y1 = (*vecs)[t1.first.t1].y(); + const osg::Vec3::value_type z1 = (*vecs)[t1.first.t1].z(); - if (t1.second != t2.second) - { - const osg::Geometry *g = geode.getDrawable( t2.second )->asGeometry(); - vecs = static_cast(g->getVertexArray()); - }; - const osg::Vec3::value_type x2 = (*vecs)[t2.first.t1].x(); - const osg::Vec3::value_type y2 = (*vecs)[t2.first.t1].y(); - const osg::Vec3::value_type z2 = (*vecs)[t2.first.t1].z(); - int val1 = inWhichBox(x1,y1,z1); - int val2 = inWhichBox(x2,y2,z2); + if (t1.second != t2.second) + { + const osg::Geometry* g = geode.getDrawable( t2.second )->asGeometry(); + vecs = static_cast(g->getVertexArray()); + } + const osg::Vec3::value_type x2 = (*vecs)[t2.first.t1].x(); + const osg::Vec3::value_type y2 = (*vecs)[t2.first.t1].y(); + const osg::Vec3::value_type z2 = (*vecs)[t2.first.t1].z(); + int val1 = inWhichBox(x1,y1,z1); + int val2 = inWhichBox(x2,y2,z2); - return (val1 < val2); + return (val1 < val2); }; void -WriterCompareTriangle::setMaxMin(unsigned int & nbVerticesX, - unsigned int & nbVerticesY, - unsigned int & nbVerticesZ) const +WriterCompareTriangle::setMaxMin(unsigned int& nbVerticesX, + unsigned int& nbVerticesY, + unsigned int& nbVerticesZ) const { - static const unsigned int min = 1; - if (nbVerticesX < min) - nbVerticesX = min; - if (nbVerticesY < min) - nbVerticesY = min; - if (nbVerticesZ < min) - nbVerticesZ = min; + static const unsigned int min = 1; + if (nbVerticesX < min) + nbVerticesX = min; + if (nbVerticesY < min) + nbVerticesY = min; + if (nbVerticesZ < min) + nbVerticesZ = min; - static const unsigned int max = 20; + static const unsigned int max = 20; - if (nbVerticesX > max) - nbVerticesX = max; - if (nbVerticesY > max) - nbVerticesY = max; - if (nbVerticesZ > max) - nbVerticesZ = max; + if (nbVerticesX > max) + nbVerticesX = max; + if (nbVerticesY > max) + nbVerticesY = max; + if (nbVerticesZ > max) + nbVerticesZ = max; } void -WriterCompareTriangle::cutscene(int nbVertices, - const osg::BoundingBox & sceneBox) +WriterCompareTriangle::cutscene(int nbVertices, + const osg::BoundingBox& sceneBox) { - osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min; + osg::BoundingBox::vec_type length = sceneBox._max - sceneBox._min; - static const unsigned int k = 4; + static const unsigned int k = 4; - unsigned int nbVerticesX = (nbVertices * k) / (length.z() * length.y()); - unsigned int nbVerticesY = (nbVertices * k) / (length.z() * length.x()); - unsigned int nbVerticesZ = (nbVertices * k) / (length.x() * length.y()); + unsigned int nbVerticesX = (nbVertices * k) / (length.z() * length.y()); + unsigned int nbVerticesY = (nbVertices * k) / (length.z() * length.x()); + unsigned int nbVerticesZ = (nbVertices * k) / (length.x() * length.y()); - setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); // This function prevent from cut scene in too many blocs + setMaxMin (nbVerticesX, nbVerticesY, nbVerticesZ); - osg::notify(osg::DEBUG_INFO) << "Cutting x by " << nbVerticesX << std::endl - << "Cutting y by " << nbVerticesY << std::endl - << "Cutting z by " << nbVerticesZ << std::endl; + osg::notify(osg::DEBUG_INFO) << "Cutting x by " << nbVerticesX << std::endl + << "Cutting y by " << nbVerticesY << std::endl + << "Cutting z by " << nbVerticesZ << std::endl; - osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; //This 3 lines set the size of a bloc in x, y and z - osg::BoundingBox::value_type blocY = length.y() / nbVerticesY; - osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ; + osg::BoundingBox::value_type blocX = length.x() / nbVerticesX; //These 3 lines set the size of a box in x, y and z + osg::BoundingBox::value_type blocY = length.y() / nbVerticesY; + osg::BoundingBox::value_type blocZ = length.z() / nbVerticesZ; - boxList.reserve(nbVerticesX * nbVerticesY * nbVerticesZ); - short yinc = 1; - short xinc = 1; - unsigned int y = 0; - unsigned int x = 0; - for (unsigned int z = 0; z < nbVerticesZ; ++z) - { - while (x < nbVerticesX && x >= 0) - { - while (y < nbVerticesY && y >= 0) - { - osg::BoundingBox::value_type xMin = sceneBox.xMin() + x * blocX; - if (x == 0) //to prevent from mesh with no case - xMin -= 10; + boxList.reserve(nbVerticesX * nbVerticesY * nbVerticesZ); + short yinc = 1; + short xinc = 1; + unsigned int y = 0; + unsigned int x = 0; + for (unsigned int z = 0; z < nbVerticesZ; ++z) + { + while (x < nbVerticesX && x >= 0) + { + while (y < nbVerticesY && y >= 0) + { + osg::BoundingBox::value_type xMin = sceneBox.xMin() + x * blocX; + if (x == 0) //to prevent from mesh with no case + xMin -= 10; - osg::BoundingBox::value_type yMin = sceneBox.yMin() + y * blocY; - if (y == 0) //to prevent from mesh with no case - yMin -= 10; + osg::BoundingBox::value_type yMin = sceneBox.yMin() + y * blocY; + if (y == 0) //to prevent from mesh with no case + yMin -= 10; - osg::BoundingBox::value_type zMin = sceneBox.zMin() + z * blocZ; - if (z == 0) //to prevent from mesh with no case - zMin -= 10; + osg::BoundingBox::value_type zMin = sceneBox.zMin() + z * blocZ; + if (z == 0) //to prevent from mesh with no case + zMin -= 10; - osg::BoundingBox::value_type xMax = sceneBox.xMin() + (x + 1) * blocX; - if (x == nbVerticesX - 1) //to prevent from mesh with no case - xMax += 10; + osg::BoundingBox::value_type xMax = sceneBox.xMin() + (x + 1) * blocX; + if (x == nbVerticesX - 1) //to prevent from mesh with no case + xMax += 10; - osg::BoundingBox::value_type yMax = sceneBox.yMin() + (y + 1) * blocY; - if (y == nbVerticesY - 1) //to prevent from mesh with no case - yMax += 10; + osg::BoundingBox::value_type yMax = sceneBox.yMin() + (y + 1) * blocY; + if (y == nbVerticesY - 1) //to prevent from mesh with no case + yMax += 10; - osg::BoundingBox::value_type zMax = sceneBox.zMin() + (z + 1) * blocZ; - if (z == nbVerticesZ - 1) //to prevent from mesh with no case - zMax += 10; + osg::BoundingBox::value_type zMax = sceneBox.zMin() + (z + 1) * blocZ; + if (z == nbVerticesZ - 1) //to prevent from mesh with no case + zMax += 10; - boxList.push_back(osg::BoundingBox(xMin, // Add a bloc to the list - yMin, - zMin, - xMax, - yMax, - zMax)); - y += yinc; - } - yinc = -yinc; - y += yinc; - x += xinc; - } - xinc = -xinc; - x += xinc; - } + boxList.push_back(osg::BoundingBox(xMin, // Add a box to the list + yMin, + zMin, + xMax, + yMax, + zMax)); + y += yinc; + } + yinc = -yinc; + y += yinc; + x += xinc; + } + xinc = -xinc; + x += xinc; + } } int WriterCompareTriangle::inWhichBox(const osg::Vec3::value_type x, - const osg::Vec3::value_type y, - const osg::Vec3::value_type z) const + const osg::Vec3::value_type y, + const osg::Vec3::value_type z) const { - for (unsigned int i = 0; i < boxList.size(); ++i) - { - if (x >= boxList[i].xMin() && - x < boxList[i].xMax() && - y >= boxList[i].yMin() && - y < boxList[i].yMax() && - z >= boxList[i].zMin() && - z < boxList[i].zMax()) - { - return i; - } - } - throw "Point is not in any blocs"; + for (unsigned int i = 0; i < boxList.size(); ++i) + { + if (x >= boxList[i].xMin() && + x < boxList[i].xMax() && + y >= boxList[i].yMin() && + y < boxList[i].yMax() && + z >= boxList[i].zMin() && + z < boxList[i].zMax()) + { + return i; + } + } + throw "Point is not in any box"; } \ No newline at end of file diff --git a/src/osgPlugins/fbx/WriterCompareTriangle.h b/src/osgPlugins/fbx/WriterCompareTriangle.h index bcfec0035..17a83d01a 100644 --- a/src/osgPlugins/fbx/WriterCompareTriangle.h +++ b/src/osgPlugins/fbx/WriterCompareTriangle.h @@ -7,45 +7,45 @@ struct Triangle { - unsigned int t1; - unsigned int t2; - unsigned int t3; - unsigned int material; + unsigned int t1; + unsigned int t2; + unsigned int t3; + unsigned int material; }; class WriterCompareTriangle { public: - WriterCompareTriangle(const osg::Geode & geode, - unsigned int nbVertices); + WriterCompareTriangle(const osg::Geode& geode, + unsigned int nbVertices); - bool operator()(const std::pair & t1, - const std::pair & t2) const; + bool operator()(const std::pair& t1, + const std::pair& t2) const; private: - void // This function prevent from cut scene in too many blocs - setMaxMin(unsigned int & nbVerticesX, - unsigned int & nbVerticesY, - unsigned int & nbVerticesZ) const; + void // This function prevents the scene being cut into too many boxes + setMaxMin(unsigned int& nbVerticesX, + unsigned int& nbVerticesY, + unsigned int& nbVerticesZ) const; - /** - * Cut the scene in different bloc to sort. - * \param nbVertices is the number of vertice in mesh. - * \param sceneBox contain the size of the scene. - */ - void - cutscene(int nbVertices, - const osg::BoundingBox & sceneBox); + /** + * Cut the scene in different box to sort. + * \param nbVertices is the number of vertices in mesh. + * \param sceneBox contain the size of the scene. + */ + void + cutscene(int nbVertices, + const osg::BoundingBox& sceneBox); - /** - * Find in which box those points are. - * \return the place of the box in the vector. - * \sa See cutScene() about the definition of the boxes for faces sorting. - */ - int inWhichBox(const osg::Vec3::value_type x, - const osg::Vec3::value_type y, - const osg::Vec3::value_type z) const; + /** + * Find in which box those points are. + * \return the place of the box in the vector. + * \sa See cutScene() about the definition of the boxes for faces sorting. + */ + int inWhichBox(const osg::Vec3::value_type x, + const osg::Vec3::value_type y, + const osg::Vec3::value_type z) const; - const osg::Geode & geode; - std::vector boxList; + const osg::Geode& geode; + std::vector boxList; }; #endif // _3DS_WRITER_COMPARE_TRIANGLE_HEADER__ \ No newline at end of file diff --git a/src/osgPlugins/fbx/fbxRMesh.cpp b/src/osgPlugins/fbx/fbxRMesh.cpp index 0cc5cb3c4..f2ada28f2 100644 --- a/src/osgPlugins/fbx/fbxRMesh.cpp +++ b/src/osgPlugins/fbx/fbxRMesh.cpp @@ -29,28 +29,12 @@ enum GeometryType GEOMETRY_MORPH }; -osg::Vec3 convertVec3(const KFbxVector4& v) +osg::Vec3d convertVec3(const KFbxVector4& v) { - return osg::Vec3( - static_cast(v[0]), - static_cast(v[1]), - static_cast(v[2])); -} - -osg::Vec2 convertVec2(const KFbxVector2& v) -{ - return osg::Vec2( - static_cast(v[0]), - static_cast(v[1])); -} - -osg::Vec4 convertColor(const KFbxColor& color) -{ - return osg::Vec4( - static_cast(color.mRed), - static_cast(color.mGreen), - static_cast(color.mBlue), - static_cast(color.mAlpha)); + return osg::Vec3d( + v[0], + v[1], + v[2]); } template @@ -136,9 +120,25 @@ FbxT getElement(const KFbxLayerElementTemplate* pLayerElement, typedef std::map > GeometryMap; +osg::Array* createVec2Array(bool doublePrecision) +{ + if (doublePrecision) return new osg::Vec2dArray; + else return new osg::Vec2Array; +} +osg::Array* createVec3Array(bool doublePrecision) +{ + if (doublePrecision) return new osg::Vec3dArray; + else return new osg::Vec3Array; +} +osg::Array* createVec4Array(bool doublePrecision) +{ + if (doublePrecision) return new osg::Vec4dArray; + else return new osg::Vec4Array; +} + osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, std::vector& stateSetList, - GeometryType gt, unsigned int mti, bool bNormal, bool bTexCoord, bool bColor) + GeometryType gt, unsigned int mti, bool bNormal, bool bTexCoord, bool bColor, const osgDB::Options& options) { GeometryMap::iterator it = geometryMap.find(mti); @@ -157,10 +157,12 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, pGeometry = new osg::Geometry; } - pGeometry->setVertexData(osg::Geometry::ArrayData(new osg::Vec3Array, osg::Geometry::BIND_PER_VERTEX)); - if (bNormal) pGeometry->setNormalData(osg::Geometry::ArrayData(new osg::Vec3Array, osg::Geometry::BIND_PER_VERTEX)); - if (bTexCoord) pGeometry->setTexCoordData(0, osg::Geometry::ArrayData(new osg::Vec2Array, osg::Geometry::BIND_PER_VERTEX)); - if (bColor) pGeometry->setColorData(osg::Geometry::ArrayData(new osg::Vec4Array, osg::Geometry::BIND_PER_VERTEX)); + osgDB::Options::PrecisionHint precision = options.getPrecisionHint(); + + pGeometry->setVertexData(osg::Geometry::ArrayData(createVec3Array((precision & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0), osg::Geometry::BIND_PER_VERTEX)); + if (bNormal) pGeometry->setNormalData(osg::Geometry::ArrayData(createVec3Array((precision & osgDB::Options::DOUBLE_PRECISION_NORMAL) != 0), osg::Geometry::BIND_PER_VERTEX)); + if (bTexCoord) pGeometry->setTexCoordData(0, osg::Geometry::ArrayData(createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Geometry::BIND_PER_VERTEX)); + if (bColor) pGeometry->setColorData(osg::Geometry::ArrayData(createVec4Array((precision & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0), osg::Geometry::BIND_PER_VERTEX)); if (mti < stateSetList.size()) { @@ -286,6 +288,51 @@ void addBindMatrix( BindMatrixMap::key_type(pBone, pRigGeometry), bindMatrix)); } +void addVec2ArrayElement(osg::Array& a, const KFbxVector2& v) +{ + if (a.getType() == osg::Array::Vec2dArrayType) + { + static_cast(a).push_back(osg::Vec2d(v[0], v[1])); + } + else + { + static_cast(a).push_back(osg::Vec2( + static_cast(v[0]), + static_cast(v[1]))); + } +} + +void addVec3ArrayElement(osg::Array& a, const KFbxVector4& v) +{ + if (a.getType() == osg::Array::Vec3dArrayType) + { + static_cast(a).push_back(osg::Vec3d(v[0], v[1], v[2])); + } + else + { + static_cast(a).push_back(osg::Vec3( + static_cast(v[0]), + static_cast(v[1]), + static_cast(v[2]))); + } +} + +void addColorArrayElement(osg::Array& a, const KFbxColor& c) +{ + if (a.getType() == osg::Array::Vec4dArrayType) + { + static_cast(a).push_back(osg::Vec4d(c.mRed, c.mGreen, c.mBlue, c.mAlpha)); + } + else + { + static_cast(a).push_back(osg::Vec4( + static_cast(c.mRed), + static_cast(c.mGreen), + static_cast(c.mBlue), + static_cast(c.mAlpha))); + } +} + osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, KFbxNode* pNode, KFbxMesh* fbxMesh, osg::ref_ptr& pAnimationManager, @@ -293,7 +340,8 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, const char* szName, BindMatrixMap& boneBindMatrices, const std::set& fbxSkeletons, - std::map& skeletonMap) + std::map& skeletonMap, + const osgDB::Options& options) { GeometryMap geometryMap; @@ -351,16 +399,12 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, osg::Geometry* pGeometry = getGeometry(pGeode, geometryMap, stateSetList, geomType, materialIndex, - pFbxNormals != 0, pFbxUVs != 0, pFbxColors != 0); + pFbxNormals != 0, pFbxUVs != 0, pFbxColors != 0, options); - osg::Vec3Array* pVertices = static_cast( - pGeometry->getVertexArray()); - osg::Vec3Array* pNormals = static_cast( - pGeometry->getNormalArray()); - osg::Vec2Array* pTexCoords = static_cast( - pGeometry->getTexCoordArray(0)); - osg::Vec4Array* pColors = static_cast( - pGeometry->getColorArray()); + osg::Array* pVertices = pGeometry->getVertexArray(); + osg::Array* pNormals = pGeometry->getNormalArray(); + osg::Array* pTexCoords = pGeometry->getTexCoordArray(0); + osg::Array* pColors = pGeometry->getColorArray(); int nVertex0 = nVertex; nVertex += (std::min)(2, lPolygonSize); @@ -372,13 +416,13 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, v1 = fbxMesh->GetPolygonVertex(i, j - 1), v2 = fbxMesh->GetPolygonVertex(i, j); - fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->size()))); - fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v1, GIPair(pGeometry, pVertices->size() + 1))); - fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v2, GIPair(pGeometry, pVertices->size() + 2))); + fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->getNumElements()))); + fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v1, GIPair(pGeometry, pVertices->getNumElements() + 1))); + fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v2, GIPair(pGeometry, pVertices->getNumElements() + 2))); - pVertices->push_back(convertVec3(pFbxVertices[v0])); - pVertices->push_back(convertVec3(pFbxVertices[v1])); - pVertices->push_back(convertVec3(pFbxVertices[v2])); + addVec3ArrayElement(*pVertices, pFbxVertices[v0]); + addVec3ArrayElement(*pVertices, pFbxVertices[v1]); + addVec3ArrayElement(*pVertices, pFbxVertices[v2]); if (pNormals) { @@ -386,27 +430,27 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, int n1 = getVertexIndex(pFbxNormals, fbxMesh, i, j - 1, nVertex - 1); int n2 = getVertexIndex(pFbxNormals, fbxMesh, i, j, nVertex); - osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->size()), n0)); - osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->size() + 1), n1)); - osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->size() + 2), n2)); + osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements()), n0)); + osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements() + 1), n1)); + osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements() + 2), n2)); - pNormals->push_back(convertVec3(pFbxNormals->GetDirectArray().GetAt(n0))); - pNormals->push_back(convertVec3(pFbxNormals->GetDirectArray().GetAt(n1))); - pNormals->push_back(convertVec3(pFbxNormals->GetDirectArray().GetAt(n2))); + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0)); + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n1)); + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n2)); } if (pTexCoords) { - pTexCoords->push_back(convertVec2(getElement(pFbxUVs, fbxMesh, i, 0, nVertex0))); - pTexCoords->push_back(convertVec2(getElement(pFbxUVs, fbxMesh, i, j - 1, nVertex - 1))); - pTexCoords->push_back(convertVec2(getElement(pFbxUVs, fbxMesh, i, j, nVertex))); + addVec2ArrayElement(*pTexCoords, getElement(pFbxUVs, fbxMesh, i, 0, nVertex0)); + addVec2ArrayElement(*pTexCoords, getElement(pFbxUVs, fbxMesh, i, j - 1, nVertex - 1)); + addVec2ArrayElement(*pTexCoords, getElement(pFbxUVs, fbxMesh, i, j, nVertex)); } if (pColors) { - pColors->push_back(convertColor(getElement(pFbxColors, fbxMesh, i, 0, nVertex0))); - pColors->push_back(convertColor(getElement(pFbxColors, fbxMesh, i, j - 1, nVertex - 1))); - pColors->push_back(convertColor(getElement(pFbxColors, fbxMesh, i, j, nVertex))); + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, 0, nVertex0)); + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, j - 1, nVertex - 1)); + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, j, nVertex)); } } } @@ -554,7 +598,7 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, int nControlPoints = pMorphShape->GetControlPointsCount(); for (int fbxIndex = 0; fbxIndex < nControlPoints; ++fbxIndex) { - osg::Vec3 vPos = convertVec3(pControlPoints[fbxIndex]); + osg::Vec3d vPos = convertVec3(pControlPoints[fbxIndex]); for (FbxToOsgVertexMap::const_iterator it = fbxToOsgVertMap.find(fbxIndex); it != fbxToOsgVertMap.end() && @@ -564,13 +608,29 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, osgAnimation::MorphGeometry& morphGeom = dynamic_cast(*gi.first); osg::Geometry* pGeometry = morphGeom.getMorphTarget(i).getGeometry(); - osg::Vec3Array* pVertices = static_cast(pGeometry->getVertexArray()); - (*pVertices)[gi.second] = vPos; - if (pFbxShapeNormals) + if (pGeometry->getVertexArray()->getType() == osg::Array::Vec3dArrayType) { - if (osg::Vec3Array* pNormals = static_cast(pGeometry->getNormalArray())) + osg::Vec3dArray* pVertices = static_cast(pGeometry->getVertexArray()); + (*pVertices)[gi.second] = vPos; + } + else + { + osg::Vec3Array* pVertices = static_cast(pGeometry->getVertexArray()); + (*pVertices)[gi.second] = vPos; + } + + if (pFbxShapeNormals && pGeometry->getNormalArray()) + { + if (pGeometry->getNormalArray()->getType() == osg::Array::Vec3dArrayType) { + osg::Vec3dArray* pNormals = static_cast(pGeometry->getNormalArray()); + (*pNormals)[gi.second] = convertVec3( + pFbxShapeNormals->GetDirectArray().GetAt(osgToFbxNormMap[gi])); + } + else + { + osg::Vec3Array* pNormals = static_cast(pGeometry->getNormalArray()); (*pNormals)[gi.second] = convertVec3( pFbxShapeNormals->GetDirectArray().GetAt(osgToFbxNormMap[gi])); } @@ -631,7 +691,8 @@ osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager, std::vector& stateSetList, BindMatrixMap& boneBindMatrices, const std::set& fbxSkeletons, - std::map& skeletonMap) + std::map& skeletonMap, + const osgDB::Options& options) { KFbxMesh* lMesh = dynamic_cast(pNode->GetNodeAttribute()); @@ -641,5 +702,5 @@ osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager, } return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList, - pNode->GetName(), boneBindMatrices, fbxSkeletons, skeletonMap); + pNode->GetName(), boneBindMatrices, fbxSkeletons, skeletonMap, options); } diff --git a/src/osgPlugins/fbx/fbxRMesh.h b/src/osgPlugins/fbx/fbxRMesh.h index ffac5dbcc..18d589cae 100644 --- a/src/osgPlugins/fbx/fbxRMesh.h +++ b/src/osgPlugins/fbx/fbxRMesh.h @@ -12,6 +12,7 @@ osgDB::ReaderWriter::ReadResult readFbxMesh( std::vector&, BindMatrixMap& boneBindMatrices, const std::set& fbxSkeletons, - std::map& skeletonMap); + std::map& skeletonMap, + const osgDB::Options&); #endif diff --git a/src/osgPlugins/fbx/fbxRNode.cpp b/src/osgPlugins/fbx/fbxRNode.cpp index 91356ed95..79bd77b6d 100644 --- a/src/osgPlugins/fbx/fbxRNode.cpp +++ b/src/osgPlugins/fbx/fbxRNode.cpp @@ -326,7 +326,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( BindMatrixMap& boneBindMatrices, const std::set& fbxSkeletons, std::map& skeletonMap, - const osgDB::Options* options) + const osgDB::Options& options) { if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute()) { @@ -432,7 +432,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( size_t bindMatrixCount = boneBindMatrices.size(); osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager, pNode, pAnimationManager, stateSetList, boneBindMatrices, - fbxSkeletons, skeletonMap); + fbxSkeletons, skeletonMap, options); if (meshRes.error()) { return meshRes; diff --git a/src/osgPlugins/fbx/fbxRNode.h b/src/osgPlugins/fbx/fbxRNode.h index 287ad5319..dd9ddb580 100644 --- a/src/osgPlugins/fbx/fbxRNode.h +++ b/src/osgPlugins/fbx/fbxRNode.h @@ -25,6 +25,6 @@ osgDB::ReaderWriter::ReadResult readFbxNode( BindMatrixMap& boneBindMatrices, const std::set& fbxSkeletons, std::map& skeletonMap, - const osgDB::Options* options = NULL); + const osgDB::Options&); #endif