From 5b603191b3d96e0e0d1a12def1a3b387803e66c2 Mon Sep 17 00:00:00 2001 From: Michael PLATINGS Date: Tue, 17 Aug 2010 13:25:46 +0000 Subject: [PATCH] From Donn Mielcarek: The fbx plugin won't compile using gcc 4.3.2. I made the following minor changes: 1. WriterNodeVisitor.cpp needed limits.h added to the headers. 2. gcc does not allow structures to be defined inside of functions, so I moved the definition of PolygonRef out of the function to a global scope (right above the function readMesh). I also removed a bunch of embedded carriage returns --- src/osgPlugins/fbx/WriterNodeVisitor.cpp | 1 + src/osgPlugins/fbx/fbxRMesh.cpp | 562 ++++++++++++----------- 2 files changed, 283 insertions(+), 280 deletions(-) diff --git a/src/osgPlugins/fbx/WriterNodeVisitor.cpp b/src/osgPlugins/fbx/WriterNodeVisitor.cpp index 6b178279e..51025954c 100644 --- a/src/osgPlugins/fbx/WriterNodeVisitor.cpp +++ b/src/osgPlugins/fbx/WriterNodeVisitor.cpp @@ -12,6 +12,7 @@ * The OSG homepage is http://www.openscenegraph.org/ */ +#include // required for UINT_MAX #include #include #include diff --git a/src/osgPlugins/fbx/fbxRMesh.cpp b/src/osgPlugins/fbx/fbxRMesh.cpp index 1a79625d9..c1fb79efa 100644 --- a/src/osgPlugins/fbx/fbxRMesh.cpp +++ b/src/osgPlugins/fbx/fbxRMesh.cpp @@ -7,10 +7,10 @@ #include #include #include -#include +#include #include -#include +#include #include @@ -217,13 +217,13 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, if (lightmapTextures) { double factor = ssc.diffuseFactor; - osg::ref_ptr texenv = new osg::TexEnvCombine(); - texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); - texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); - texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); - texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); - stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); } // setup transparency @@ -250,13 +250,13 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, //In practice factor will always be zero, hence the RGB of the //opacity map will be ignored. The alpha will modulate the previous alpha. double factor = ssc.opacityFactor; - osg::ref_ptr texenv = new osg::TexEnvCombine(); - texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); - texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); - texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); - texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); - stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); // setup transparency... if (!transparent && ssc.opacityTexture->getImage()) @@ -269,19 +269,19 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, ssc.reflectionTexture.get()); // setup spherical map... - osg::ref_ptr texgen = new osg::TexGen(); - texgen->setMode(osg::TexGen::SPHERE_MAP); + osg::ref_ptr texgen = new osg::TexGen(); + texgen->setMode(osg::TexGen::SPHERE_MAP); stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texgen.get(), osg::StateAttribute::ON); // setup combiner for factor... double factor = ssc.reflectionFactor; - osg::ref_ptr texenv = new osg::TexEnvCombine(); - texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); - texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); - texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); - texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); - texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); - stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); } // emissive texture map @@ -297,14 +297,14 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON); } - stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, ssc.emissiveTexture.get()); + stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, ssc.emissiveTexture.get()); } // add more texture maps here... if (transparent) { - stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); } } @@ -364,20 +364,20 @@ void readAnimation(KFbxNode* pNode, KFbxScene& fbxScene, const std::string& targ osg::ref_ptr& pAnimationManager, KFbxMesh* pMesh, int nShape) { - for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i) - { - KFbxAnimStack* pAnimStack = KFbxCast(fbxScene.GetSrcObject(FBX_TYPE(KFbxAnimStack), i)); - - int nbAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(KFbxAnimLayer)); - + for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i) + { + KFbxAnimStack* pAnimStack = KFbxCast(fbxScene.GetSrcObject(FBX_TYPE(KFbxAnimStack), i)); + + int nbAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(KFbxAnimLayer)); + const char* pTakeName = pAnimStack->GetName(); if (!pTakeName || !*pTakeName) continue; - for (int j = 0; j < nbAnimLayers; j++) - { - KFbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(KFbxAnimLayer), j); + for (int j = 0; j < nbAnimLayers; j++) + { + KFbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(KFbxAnimLayer), j); KFbxAnimCurve* pCurve = pMesh->GetShapeChannel(nShape, pAnimLayer); if (!pCurve) @@ -407,8 +407,8 @@ void readAnimation(KFbxNode* pNode, KFbxScene& fbxScene, const std::string& targ ss << nShape; pChannel->setName(ss.str()); addChannel(pChannel, pAnimationManager, pTakeName); - } - } + } + } { } @@ -523,56 +523,56 @@ const KFbxLayerElementUV* getUVElementForChannel(std::string uvChannelName, return 0; } -typedef std::pair GIPair; -typedef std::multimap FbxToOsgVertexMap; -typedef std::map OsgToFbxNormalMap; - -void readMeshTriangle(const KFbxMesh * fbxMesh, int i /*polygonIndex*/, - int posInPoly0, int posInPoly1, int posInPoly2, - int meshVertex0, int meshVertex1, int meshVertex2, - FbxToOsgVertexMap& fbxToOsgVertMap, - OsgToFbxNormalMap& osgToFbxNormMap, - const KFbxVector4* pFbxVertices, - const KFbxLayerElementNormal* pFbxNormals, - const KFbxLayerElementUV* pFbxUVs_diffuse, - const KFbxLayerElementUV* pFbxUVs_opacity, - const KFbxLayerElementUV* pFbxUVs_emissive, - const KFbxLayerElementVertexColor* pFbxColors, - osg::Geometry* pGeometry, - osg::Array* pVertices, - osg::Array* pNormals, - osg::Array* pTexCoords_diffuse, - osg::Array* pTexCoords_opacity, - osg::Array* pTexCoords_emissive, - osg::Array* pColors) -{ - int v0 = fbxMesh->GetPolygonVertex(i, posInPoly0), - v1 = fbxMesh->GetPolygonVertex(i, posInPoly1), - v2 = fbxMesh->GetPolygonVertex(i, posInPoly2); - - 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))); - - addVec3ArrayElement(*pVertices, pFbxVertices[v0]); - addVec3ArrayElement(*pVertices, pFbxVertices[v1]); - addVec3ArrayElement(*pVertices, pFbxVertices[v2]); - - if (pNormals) - { - int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly0, meshVertex0); - int n1 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly1, meshVertex1); - int n2 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly2, meshVertex2); - - 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)); - - addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0)); - addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n1)); - addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n2)); - } - +typedef std::pair GIPair; +typedef std::multimap FbxToOsgVertexMap; +typedef std::map OsgToFbxNormalMap; + +void readMeshTriangle(const KFbxMesh * fbxMesh, int i /*polygonIndex*/, + int posInPoly0, int posInPoly1, int posInPoly2, + int meshVertex0, int meshVertex1, int meshVertex2, + FbxToOsgVertexMap& fbxToOsgVertMap, + OsgToFbxNormalMap& osgToFbxNormMap, + const KFbxVector4* pFbxVertices, + const KFbxLayerElementNormal* pFbxNormals, + const KFbxLayerElementUV* pFbxUVs_diffuse, + const KFbxLayerElementUV* pFbxUVs_opacity, + const KFbxLayerElementUV* pFbxUVs_emissive, + const KFbxLayerElementVertexColor* pFbxColors, + osg::Geometry* pGeometry, + osg::Array* pVertices, + osg::Array* pNormals, + osg::Array* pTexCoords_diffuse, + osg::Array* pTexCoords_opacity, + osg::Array* pTexCoords_emissive, + osg::Array* pColors) +{ + int v0 = fbxMesh->GetPolygonVertex(i, posInPoly0), + v1 = fbxMesh->GetPolygonVertex(i, posInPoly1), + v2 = fbxMesh->GetPolygonVertex(i, posInPoly2); + + 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))); + + addVec3ArrayElement(*pVertices, pFbxVertices[v0]); + addVec3ArrayElement(*pVertices, pFbxVertices[v1]); + addVec3ArrayElement(*pVertices, pFbxVertices[v2]); + + if (pNormals) + { + int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly0, meshVertex0); + int n1 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly1, meshVertex1); + int n2 = getVertexIndex(pFbxNormals, fbxMesh, i, posInPoly2, meshVertex2); + + 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)); + + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0)); + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n1)); + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n2)); + } + // add texture maps data (avoid duplicates)... if (pTexCoords_diffuse) { @@ -596,57 +596,68 @@ void readMeshTriangle(const KFbxMesh * fbxMesh, int i /*polygonIndex*/, addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, posInPoly2, meshVertex2)); } // add more texture maps here... - - if (pColors) - { - addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly0, meshVertex0)); - addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly1, meshVertex1)); - addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly2, meshVertex2)); + + if (pColors) + { + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly0, meshVertex0)); + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly1, meshVertex1)); + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, posInPoly2, meshVertex2)); } -} - -/// Says if a quad should be split using vertices 02 (or else 13) -bool quadSplit02(const KFbxMesh * fbxMesh, int i /*polygonIndex*/, - int posInPoly0, int posInPoly1, int posInPoly2, int posInPoly3, - const KFbxVector4* pFbxVertices) -{ - // Algorithm may be a bit dumb. If you got a faster one, feel free to change. - // Here we test each of the 4 triangles and see if there is one in the opposite direction. - // Triangles: 012, 023, 013, 123 - // For this, we do a cross product to get normals. We say here the first triangle is the reference, and do a dot product to see the direction. - // Normals: na (= (p1-p0)^(p2-p1)), nb, na, nd - // Dot products: rb (na.nb), rc, rd - // Results: - // if r*>0 => convex (02 and 13 are ok, so choose 02) - // if rb only <0, or r*<0 => concave, split on 13 - // if rc only <0, or rd<0 => concave, split on 02 - // else unhandled (crossed polygon?) => choose 02 - // In short: - // if rb only <0, or r*<0 => return false - // else return true - - int v0 = fbxMesh->GetPolygonVertex(i, posInPoly0); - int v1 = fbxMesh->GetPolygonVertex(i, posInPoly1); - int v2 = fbxMesh->GetPolygonVertex(i, posInPoly2); - int v3 = fbxMesh->GetPolygonVertex(i, posInPoly3); - - osg::Vec3d p0(pFbxVertices[v0][0], pFbxVertices[v0][1], pFbxVertices[v0][2]); - osg::Vec3d p1(pFbxVertices[v1][0], pFbxVertices[v1][1], pFbxVertices[v1][2]); - osg::Vec3d p2(pFbxVertices[v2][0], pFbxVertices[v2][1], pFbxVertices[v2][2]); - osg::Vec3d p3(pFbxVertices[v3][0], pFbxVertices[v3][1], pFbxVertices[v3][2]); - - osg::Vec3d na((p1 - p0) ^ (p2 - p1)); - osg::Vec3d nb((p2 - p0) ^ (p3 - p2)); - - double rb(na * nb); - if (rb >= 0) return true; // Split at 02 - - osg::Vec3d nc((p1 - p0) ^ (p3 - p1)); - osg::Vec3d nd((p2 - p1) ^ (p3 - p2)); - double rc(na * nc); - double rd(na * nd); - return (rc >= 0 || rd >= 0); -} +} + +/// Says if a quad should be split using vertices 02 (or else 13) +bool quadSplit02(const KFbxMesh * fbxMesh, int i /*polygonIndex*/, + int posInPoly0, int posInPoly1, int posInPoly2, int posInPoly3, + const KFbxVector4* pFbxVertices) +{ + // Algorithm may be a bit dumb. If you got a faster one, feel free to change. + // Here we test each of the 4 triangles and see if there is one in the opposite direction. + // Triangles: 012, 023, 013, 123 + // For this, we do a cross product to get normals. We say here the first triangle is the reference, and do a dot product to see the direction. + // Normals: na (= (p1-p0)^(p2-p1)), nb, na, nd + // Dot products: rb (na.nb), rc, rd + // Results: + // if r*>0 => convex (02 and 13 are ok, so choose 02) + // if rb only <0, or r*<0 => concave, split on 13 + // if rc only <0, or rd<0 => concave, split on 02 + // else unhandled (crossed polygon?) => choose 02 + // In short: + // if rb only <0, or r*<0 => return false + // else return true + + int v0 = fbxMesh->GetPolygonVertex(i, posInPoly0); + int v1 = fbxMesh->GetPolygonVertex(i, posInPoly1); + int v2 = fbxMesh->GetPolygonVertex(i, posInPoly2); + int v3 = fbxMesh->GetPolygonVertex(i, posInPoly3); + + osg::Vec3d p0(pFbxVertices[v0][0], pFbxVertices[v0][1], pFbxVertices[v0][2]); + osg::Vec3d p1(pFbxVertices[v1][0], pFbxVertices[v1][1], pFbxVertices[v1][2]); + osg::Vec3d p2(pFbxVertices[v2][0], pFbxVertices[v2][1], pFbxVertices[v2][2]); + osg::Vec3d p3(pFbxVertices[v3][0], pFbxVertices[v3][1], pFbxVertices[v3][2]); + + osg::Vec3d na((p1 - p0) ^ (p2 - p1)); + osg::Vec3d nb((p2 - p0) ^ (p3 - p2)); + + double rb(na * nb); + if (rb >= 0) return true; // Split at 02 + + osg::Vec3d nc((p1 - p0) ^ (p3 - p1)); + osg::Vec3d nd((p2 - p1) ^ (p3 - p2)); + double rc(na * nc); + double rd(na * nd); + return (rc >= 0 || rd >= 0); +} + +struct PolygonRef +{ + PolygonRef(osg::Geometry* pGeometry, int numPoly, int nVertex) + : pGeometry(pGeometry), numPoly(numPoly), nVertex(nVertex) + {} + osg::Geometry* pGeometry; + int numPoly; + int nVertex; +}; +typedef std::vector PolygonRefList; osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( KFbxNode* pNode, @@ -722,20 +733,11 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( FbxToOsgVertexMap fbxToOsgVertMap; OsgToFbxNormalMap osgToFbxNormMap; - // First add only triangles and quads (easy to split into triangles without - // more processing) - // This is the reason we store polygons references: - struct PolygonRef - { - PolygonRef(osg::Geometry* pGeometry, int numPoly, int nVertex) - : pGeometry(pGeometry), numPoly(numPoly), nVertex(nVertex) - {} - osg::Geometry* pGeometry; - int numPoly; - int nVertex; - }; - typedef std::vector PolygonRefList; - PolygonRefList polygonRefList; + // First add only triangles and quads (easy to split into triangles without + // more processing) + // This is the reason we store polygons references: + + PolygonRefList polygonRefList; for (int i = 0, nVertex = 0; i < nPolys; ++i) { @@ -765,106 +767,106 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( osg::Array* pColors = pGeometry->getColorArray(); - if (lPolygonSize == 3) - { - // Triangle - readMeshTriangle(fbxMesh, i, - 0, 1, 2, - nVertex, nVertex+1, nVertex+2, - fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, - pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); - nVertex += 3; - } - else if (lPolygonSize == 4) - { - // Quad - Convert to triangles - // Use some fast specialized code to see how the should be decomposed - // Two cases : Split at '02' (012 and 023), or split at '13 (013 and 123) - bool split02 = quadSplit02(fbxMesh, i, 0, 1, 2, 3, pFbxVertices); - int p02 = split02 ? 2 : 3; // Triangle 0, point 2 - int p10 = split02 ? 0 : 1; // Triangle 1, point 0 - readMeshTriangle(fbxMesh, i, - 0, 1, p02, - nVertex, nVertex+1, nVertex+p02, - fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, - pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); - readMeshTriangle(fbxMesh, i, - p10, 2, 3, - nVertex+p10, nVertex+2, nVertex+3, - fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, - pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); - nVertex += 4; - } - else if (tessellatePolygons) - { - // Polygons - Store to add after triangles - polygonRefList.push_back(PolygonRef(pGeometry, i, nVertex)); - nVertex += lPolygonSize; - } - else - { - int nVertex0 = nVertex; - nVertex += (std::min)(2, lPolygonSize); - - for (int j = 2; j < lPolygonSize; ++j, ++nVertex) - { - readMeshTriangle(fbxMesh, i, - 0, j - 1, j, - nVertex0, nVertex - 1, nVertex, - fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, - pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); - } - } + if (lPolygonSize == 3) + { + // Triangle + readMeshTriangle(fbxMesh, i, + 0, 1, 2, + nVertex, nVertex+1, nVertex+2, + fbxToOsgVertMap, osgToFbxNormMap, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pGeometry, + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + nVertex += 3; + } + else if (lPolygonSize == 4) + { + // Quad - Convert to triangles + // Use some fast specialized code to see how the should be decomposed + // Two cases : Split at '02' (012 and 023), or split at '13 (013 and 123) + bool split02 = quadSplit02(fbxMesh, i, 0, 1, 2, 3, pFbxVertices); + int p02 = split02 ? 2 : 3; // Triangle 0, point 2 + int p10 = split02 ? 0 : 1; // Triangle 1, point 0 + readMeshTriangle(fbxMesh, i, + 0, 1, p02, + nVertex, nVertex+1, nVertex+p02, + fbxToOsgVertMap, osgToFbxNormMap, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pGeometry, + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + readMeshTriangle(fbxMesh, i, + p10, 2, 3, + nVertex+p10, nVertex+2, nVertex+3, + fbxToOsgVertMap, osgToFbxNormMap, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pGeometry, + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + nVertex += 4; + } + else if (tessellatePolygons) + { + // Polygons - Store to add after triangles + polygonRefList.push_back(PolygonRef(pGeometry, i, nVertex)); + nVertex += lPolygonSize; + } + else + { + int nVertex0 = nVertex; + nVertex += (std::min)(2, lPolygonSize); + + for (int j = 2; j < lPolygonSize; ++j, ++nVertex) + { + readMeshTriangle(fbxMesh, i, + 0, j - 1, j, + nVertex0, nVertex - 1, nVertex, + fbxToOsgVertMap, osgToFbxNormMap, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pGeometry, + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + } + } } - - for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i) - { - osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); - osg::DrawArrays* pDrawArrays = new osg::DrawArrays( - GL_TRIANGLES, 0, pGeometry->getVertexArray()->getNumElements()); - pGeometry->addPrimitiveSet(pDrawArrays); - } - - // Now add polygons - Convert to triangles - // We put vertices in their own PrimitiveSet with Mode=POLYGON; then run the - // Tessellator on the Geometry which should tessellate the polygons - // automagically. - for (PolygonRefList::iterator it = polygonRefList.begin(), itEnd=polygonRefList.end(); - it != itEnd; ++it) - { - int i = it->numPoly; - int lPolygonSize = fbxMesh->GetPolygonSize(i); - //int materialIndex = getPolygonIndex(pFbxMaterials, i); - osg::Geometry* pGeometry = it->pGeometry; - - osg::Array* pVertices = pGeometry->getVertexArray(); - osg::Array* pNormals = pGeometry->getNormalArray(); + + for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i) + { + osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); + osg::DrawArrays* pDrawArrays = new osg::DrawArrays( + GL_TRIANGLES, 0, pGeometry->getVertexArray()->getNumElements()); + pGeometry->addPrimitiveSet(pDrawArrays); + } + + // Now add polygons - Convert to triangles + // We put vertices in their own PrimitiveSet with Mode=POLYGON; then run the + // Tessellator on the Geometry which should tessellate the polygons + // automagically. + for (PolygonRefList::iterator it = polygonRefList.begin(), itEnd=polygonRefList.end(); + it != itEnd; ++it) + { + int i = it->numPoly; + int lPolygonSize = fbxMesh->GetPolygonSize(i); + //int materialIndex = getPolygonIndex(pFbxMaterials, i); + osg::Geometry* pGeometry = it->pGeometry; + + osg::Array* pVertices = pGeometry->getVertexArray(); + osg::Array* pNormals = pGeometry->getNormalArray(); osg::Array* pTexCoords_diffuse = pGeometry->getTexCoordArray(StateSetContent::DIFFUSE_TEXTURE_UNIT); osg::Array* pTexCoords_opacity = pGeometry->getTexCoordArray(StateSetContent::OPACITY_TEXTURE_UNIT); osg::Array* pTexCoords_emissive = pGeometry->getTexCoordArray(StateSetContent::EMISSIVE_TEXTURE_UNIT); - osg::Array* pColors = pGeometry->getColorArray(); - // Index of the 1st vertex of the polygon in the geometry - int osgVertex0 = pVertices->getNumElements(); - - for (int j = 0, nVertex = it->nVertex; jGetPolygonVertex(i, j); - fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->getNumElements()))); - addVec3ArrayElement(*pVertices, pFbxVertices[v0]); - if (pNormals) - { - int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, j, nVertex); - osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements()), n0)); - addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0)); - } + osg::Array* pColors = pGeometry->getColorArray(); + // Index of the 1st vertex of the polygon in the geometry + int osgVertex0 = pVertices->getNumElements(); + + for (int j = 0, nVertex = it->nVertex; jGetPolygonVertex(i, j); + fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->getNumElements()))); + addVec3ArrayElement(*pVertices, pFbxVertices[v0]); + if (pNormals) + { + int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, j, nVertex); + osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->getNumElements()), n0)); + addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n0)); + } // add texture maps data (avoid duplicates)... if (pTexCoords_diffuse) @@ -883,37 +885,37 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, j, nVertex)); } // add more texture maps here... - - if (pColors) - { - addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, j, nVertex)); - } - } - - osg::DrawArrays* pDrawArrays = new osg::DrawArrays( - GL_POLYGON, osgVertex0, pGeometry->getVertexArray()->getNumElements() - osgVertex0); - pGeometry->addPrimitiveSet(pDrawArrays); - } - - for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i) - { - osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); - - // Now split polygons if necessary - osgUtil::Tessellator tessellator; - tessellator.retessellatePolygons(*pGeometry); - - if (pGeode->getNumDrawables() > 1) - { - std::stringstream ss; - ss << pGeode->getName() << " " << i + 1; - pGeometry->setName(ss.str()); - } - else - { - pGeometry->setName(pGeode->getName()); - } - } + + if (pColors) + { + addColorArrayElement(*pColors, getElement(pFbxColors, fbxMesh, i, j, nVertex)); + } + } + + osg::DrawArrays* pDrawArrays = new osg::DrawArrays( + GL_POLYGON, osgVertex0, pGeometry->getVertexArray()->getNumElements() - osgVertex0); + pGeometry->addPrimitiveSet(pDrawArrays); + } + + for (unsigned i = 0; i < pGeode->getNumDrawables(); ++i) + { + osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry(); + + // Now split polygons if necessary + osgUtil::Tessellator tessellator; + tessellator.retessellatePolygons(*pGeometry); + + if (pGeode->getNumDrawables() > 1) + { + std::stringstream ss; + ss << pGeode->getName() << " " << i + 1; + pGeometry->setName(ss.str()); + } + else + { + pGeometry->setName(pGeode->getName()); + } + } if (geomType == GEOMETRY_RIG) { @@ -1138,4 +1140,4 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxMesh(KFbxNode* pNode, return readMesh(pNode, lMesh, stateSetList, pNode->GetName()); -} \ No newline at end of file +}