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
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
* The OSG homepage is http://www.openscenegraph.org/
|
||||
*/
|
||||
|
||||
#include <climits> // required for UINT_MAX
|
||||
#include <cassert>
|
||||
#include <osg/CullFace>
|
||||
#include <osg/MatrixTransform>
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/TexMat>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/TexEnvCombine>
|
||||
#include <osg/TexEnvCombine>
|
||||
|
||||
#include <osgUtil/TriStripVisitor>
|
||||
#include <osgUtil/Tessellator>
|
||||
#include <osgUtil/Tessellator>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
@@ -217,13 +217,13 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
|
||||
if (lightmapTextures)
|
||||
{
|
||||
double factor = ssc.diffuseFactor;
|
||||
osg::ref_ptr<osg::TexEnvCombine> 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<osg::TexEnvCombine> 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<osg::TexEnvCombine> 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<osg::TexEnvCombine> 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<osg::TexGen> texgen = new osg::TexGen();
|
||||
texgen->setMode(osg::TexGen::SPHERE_MAP);
|
||||
osg::ref_ptr<osg::TexGen> 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<osg::TexEnvCombine> 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<osg::TexEnvCombine> 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<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
KFbxMesh* pMesh, int nShape)
|
||||
{
|
||||
for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i)
|
||||
{
|
||||
KFbxAnimStack* pAnimStack = KFbxCast<KFbxAnimStack>(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<KFbxAnimStack>(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<osg::Geometry*, int> GIPair;
|
||||
typedef std::multimap<int, GIPair> FbxToOsgVertexMap;
|
||||
typedef std::map<GIPair, int> 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<osg::Geometry*, int> GIPair;
|
||||
typedef std::multimap<int, GIPair> FbxToOsgVertexMap;
|
||||
typedef std::map<GIPair, int> 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<PolygonRef> 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<PolygonRef> 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; j<lPolygonSize; ++j, ++nVertex)
|
||||
{
|
||||
int v0 = fbxMesh->GetPolygonVertex(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; j<lPolygonSize; ++j, ++nVertex)
|
||||
{
|
||||
int v0 = fbxMesh->GetPolygonVertex(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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user