Fbx writer: added support to convert geometries directly attached as node, without geodes.

This commit is contained in:
Riccardo Corsi 2017-12-20 09:52:50 +01:00
parent d2bfde30f0
commit ef8891351f
2 changed files with 84 additions and 28 deletions

View File

@ -444,7 +444,7 @@ WriterNodeVisitor::setLayerTextureAndMaterial(FbxMesh* mesh)
}
void
WriterNodeVisitor::setControlPointAndNormalsAndUV(const osg::Geode& geo,
WriterNodeVisitor::setControlPointAndNormalsAndUV(const GeometryList& geometryList,
MapIndices& index_vert,
bool texcoords,
FbxMesh* mesh)
@ -468,7 +468,7 @@ WriterNodeVisitor::setControlPointAndNormalsAndUV(const osg::Geode& geo,
for (MapIndices::iterator it = index_vert.begin(); it != index_vert.end(); ++it)
{
const osg::Geometry* pGeometry = geo.getDrawable(it->first.drawableIndex)->asGeometry();
const osg::Geometry* pGeometry = geometryList[it->first.drawableIndex];
unsigned int vertexIndex = it->first.vertexIndex;
unsigned int normalIndex = it->first.normalIndex;
@ -562,12 +562,13 @@ WriterNodeVisitor::setControlPointAndNormalsAndUV(const osg::Geode& geo,
}
}
void WriterNodeVisitor::buildFaces(const osg::Geode& geo,
void WriterNodeVisitor::buildFaces(const std::string& name,
const GeometryList& geometryList,
ListTriangle& listTriangles,
bool texcoords)
{
MapIndices index_vert;
FbxMesh* mesh = FbxMesh::Create(_pSdkManager, geo.getName().c_str());
FbxMesh* mesh = FbxMesh::Create(_pSdkManager, name.c_str());
_curFbxNode->AddNodeAttribute(mesh);
_curFbxNode->SetShadingMode(FbxNode::eTextureShading);
FbxLayer* lLayer = mesh->GetLayer(0);
@ -596,7 +597,7 @@ void WriterNodeVisitor::buildFaces(const osg::Geode& geo,
addPolygon(mesh, index_vert, it->first, it->second);
mesh->EndPolygon();
}
setControlPointAndNormalsAndUV(geo, index_vert, texcoords, mesh);
setControlPointAndNormalsAndUV(geometryList, index_vert, texcoords, mesh);
}
void WriterNodeVisitor::createListTriangle(const osg::Geometry* geo,
@ -643,37 +644,59 @@ void WriterNodeVisitor::apply(osg::Geode& node)
FbxNode* nodeFBX = FbxNode::Create(_pSdkManager, node.getName().empty() ? "DefaultName" : node.getName().c_str());
_curFbxNode->AddChild(nodeFBX);
_curFbxNode = nodeFBX;
unsigned int count = node.getNumDrawables();
ListTriangle listTriangles;
bool texcoords = false;
for (MaterialMap::iterator it = _materialMap.begin(); it != _materialMap.end(); ++it)
it->second.setIndex(-1);
_lastMaterialIndex = 0;
// collect geometries from geode
GeometryList geometryList;
for (unsigned int i = 0; i < count; ++i)
{
const osg::Geometry* g = node.getDrawable(i)->asGeometry();
if (g)
geometryList.push_back(g);
}
if(node.getStateSet()){
pushStateSet(node.getStateSet());
}
for (unsigned int i = 0; i < count; ++i)
{
const osg::Geometry* g = node.getDrawable(i)->asGeometry();
if (g != NULL)
{
pushStateSet(g->getStateSet());
createListTriangle(g, listTriangles, texcoords, i);
popStateSet(g->getStateSet());
}
}
// process geometries in batch
ProcessGeometryList(geometryList, node.getName());
if(node.getStateSet()){
popStateSet(node.getStateSet());
}
if (count > 0)
{
buildFaces(node, listTriangles, texcoords);
}
if (succeedLastApply())
traverse(node);
_curFbxNode = parent;
}
void WriterNodeVisitor::apply(osg::Geometry& geometry)
{
// here we simply create a single fbx node to assign it the mesh
// retrieved from the geometry.
// No need to push&pop the geometry state set, as it will be taken into account
// by ProcessGeometryList()
// create fbx node to contain the single geometry
FbxNode* parent = _curFbxNode;
FbxNode* nodeFBX = FbxNode::Create(_pSdkManager, geometry.getName().empty() ? "Geometry" : geometry.getName().c_str());
_curFbxNode->AddChild(nodeFBX);
_curFbxNode = nodeFBX;
// process the single geometry
GeometryList geometryList;
geometryList.push_back(&geometry);
ProcessGeometryList(geometryList, geometry.getName());
// return to parent fbx node
_curFbxNode = parent;
}
void WriterNodeVisitor::apply(osg::Group& node)
{
FbxNode* parent = _curFbxNode;
@ -711,5 +734,30 @@ void WriterNodeVisitor::apply(osg::MatrixTransform& node)
_curFbxNode = parent;
}
//////////////////////////////////////////////////////////////////////////
void WriterNodeVisitor::ProcessGeometryList(GeometryList &geometryList, const std::string& meshName)
{
ListTriangle listTriangles;
bool texcoords = false;
for (MaterialMap::iterator it = _materialMap.begin(); it != _materialMap.end(); ++it)
it->second.setIndex(-1);
_lastMaterialIndex = 0;
for (unsigned int i = 0; i < geometryList.size(); ++i)
{
const osg::Geometry* g = geometryList[i];
pushStateSet(g->getStateSet());
createListTriangle(g, listTriangles, texcoords, i);
popStateSet(g->getStateSet());
}
if (listTriangles.size() > 0){
buildFaces(meshName, geometryList, listTriangles, texcoords);
}
}
// end namespace pluginfbx
}

View File

@ -62,6 +62,7 @@ struct VertexIndex
typedef std::vector<std::pair<Triangle, int> > ListTriangle; //the int is the drawable of the triangle
typedef std::map<VertexIndex, unsigned int> MapIndices; ///< Map OSG indices to FBX mesh indices
typedef std::vector<const osg::Geometry*> GeometryList; // a list of geometries to process in batch
namespace pluginfbx
{
@ -94,9 +95,10 @@ class WriterNodeVisitor: public osg::NodeVisitor
void failedApply() { _succeedLastApply = false; }
virtual void apply(osg::Geode& node);
virtual void apply(osg::Geometry& node);
virtual void apply(osg::Group& node);
virtual void apply(osg::MatrixTransform& node);
void traverse (osg::Node& node)
{
pushStateSet(node.getStateSet());
@ -192,13 +194,19 @@ class WriterNodeVisitor: public osg::NodeVisitor
};
private:
/// process triangles and build faces for a batch of geometries
void ProcessGeometryList(GeometryList& geometryList, const std::string& meshName);
/**
* Fill the faces field of the mesh and call buildMesh().
* \param geo is the geode which contains the vertices and faces.
* \param name the name to assign to the Fbx Mesh
* \param geometryList is the list of geometries which contains the vertices and faces.
* \param listTriangles contain all the mesh's faces.
* \param texcoords tell us if we have to handle texture coordinates.
*/
void buildFaces(const osg::Geode& geo,
void buildFaces(const std::string& name,
const GeometryList& geometryList,
ListTriangle& listTriangles,
bool texcoords);
@ -206,7 +214,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
void setLayerTextureAndMaterial(FbxMesh* mesh);
/// Set Vertices, normals, and UVs
void setControlPointAndNormalsAndUV(const osg::Geode& geo,
void setControlPointAndNormalsAndUV(const GeometryList& geometryList,
MapIndices& index_vert,
bool texcoords,
FbxMesh* fbxMesh);