Fix duplicate geometries in FBX export.
The fix to allow the export of orphaned Geometry nodes accidentally duplicated those geometry nodes in 'normal' scene trees. This commit refactors the code to rely on the visitor to traverse the Geometry as opposed to traversing the Geometry in the Geode visit and the Geometry visit.
This commit is contained in:
parent
85504b45f6
commit
0c1e938bc9
@ -603,7 +603,7 @@ void WriterNodeVisitor::buildFaces(const std::string& name,
|
|||||||
void WriterNodeVisitor::createListTriangle(const osg::Geometry* geo,
|
void WriterNodeVisitor::createListTriangle(const osg::Geometry* geo,
|
||||||
ListTriangle& listTriangles,
|
ListTriangle& listTriangles,
|
||||||
bool& texcoords,
|
bool& texcoords,
|
||||||
unsigned int& drawable_n)
|
unsigned int drawable_n)
|
||||||
{
|
{
|
||||||
unsigned int nbVertices = 0;
|
unsigned int nbVertices = 0;
|
||||||
{
|
{
|
||||||
@ -638,48 +638,10 @@ void WriterNodeVisitor::createListTriangle(const osg::Geometry* geo,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriterNodeVisitor::apply(osg::Geode& node)
|
|
||||||
{
|
|
||||||
FbxNode* parent = _curFbxNode;
|
|
||||||
FbxNode* nodeFBX = FbxNode::Create(_pSdkManager, node.getName().empty() ? "DefaultName" : node.getName().c_str());
|
|
||||||
_curFbxNode->AddChild(nodeFBX);
|
|
||||||
_curFbxNode = nodeFBX;
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int count = node.getNumDrawables();
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
// process geometries in batch
|
|
||||||
processGeometryList(geometryList, node.getName());
|
|
||||||
|
|
||||||
if(node.getStateSet()){
|
|
||||||
popStateSet(node.getStateSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (succeedLastApply())
|
|
||||||
traverse(node);
|
|
||||||
|
|
||||||
_curFbxNode = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriterNodeVisitor::apply(osg::Geometry& geometry)
|
void WriterNodeVisitor::apply(osg::Geometry& geometry)
|
||||||
{
|
{
|
||||||
// here we simply create a single fbx node to assign it the mesh
|
// here we simply create a single fbx node to assign it the mesh
|
||||||
// retrieved from the geometry.
|
// 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
|
// create fbx node to contain the single geometry
|
||||||
FbxNode* parent = _curFbxNode;
|
FbxNode* parent = _curFbxNode;
|
||||||
@ -687,16 +649,21 @@ void WriterNodeVisitor::apply(osg::Geometry& geometry)
|
|||||||
_curFbxNode->AddChild(nodeFBX);
|
_curFbxNode->AddChild(nodeFBX);
|
||||||
_curFbxNode = nodeFBX;
|
_curFbxNode = nodeFBX;
|
||||||
|
|
||||||
// process the single geometry
|
_geometryList.push_back(&geometry);
|
||||||
GeometryList geometryList;
|
|
||||||
geometryList.push_back(&geometry);
|
pushStateSet(geometry.getStateSet());
|
||||||
processGeometryList(geometryList, geometry.getName());
|
createListTriangle(&geometry, _listTriangles, _texcoords, _drawableNum++);
|
||||||
|
popStateSet(geometry.getStateSet());
|
||||||
|
|
||||||
|
osg::NodeVisitor::traverse(geometry);
|
||||||
|
|
||||||
|
if (geometry.getNumParents() == 0)
|
||||||
|
buildFaces(geometry.getName(), _geometryList, _listTriangles, _texcoords);
|
||||||
|
|
||||||
// return to parent fbx node
|
// return to parent fbx node
|
||||||
_curFbxNode = parent;
|
_curFbxNode = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WriterNodeVisitor::apply(osg::Group& node)
|
void WriterNodeVisitor::apply(osg::Group& node)
|
||||||
{
|
{
|
||||||
FbxNode* parent = _curFbxNode;
|
FbxNode* parent = _curFbxNode;
|
||||||
@ -704,7 +671,20 @@ void WriterNodeVisitor::apply(osg::Group& node)
|
|||||||
FbxNode* nodeFBX = FbxNode::Create(_pSdkManager, node.getName().empty() ? "DefaultName" : node.getName().c_str());
|
FbxNode* nodeFBX = FbxNode::Create(_pSdkManager, node.getName().empty() ? "DefaultName" : node.getName().c_str());
|
||||||
_curFbxNode->AddChild(nodeFBX);
|
_curFbxNode->AddChild(nodeFBX);
|
||||||
_curFbxNode = nodeFBX;
|
_curFbxNode = nodeFBX;
|
||||||
|
|
||||||
|
_geometryList.clear();
|
||||||
|
_listTriangles.clear();
|
||||||
|
_texcoords = false;
|
||||||
|
_drawableNum = 0;
|
||||||
|
for (MaterialMap::iterator it = _materialMap.begin(); it != _materialMap.end(); ++it)
|
||||||
|
it->second.setIndex(-1);
|
||||||
|
_lastMaterialIndex = 0;
|
||||||
|
|
||||||
traverse(node);
|
traverse(node);
|
||||||
|
|
||||||
|
if (_listTriangles.size() > 0)
|
||||||
|
buildFaces(node.getName(), _geometryList, _listTriangles, _texcoords);
|
||||||
|
|
||||||
_curFbxNode = parent;
|
_curFbxNode = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,30 +714,5 @@ void WriterNodeVisitor::apply(osg::MatrixTransform& node)
|
|||||||
_curFbxNode = parent;
|
_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
|
// end namespace pluginfbx
|
||||||
}
|
}
|
||||||
|
@ -78,23 +78,17 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
|||||||
const std::string& srcDirectory) :
|
const std::string& srcDirectory) :
|
||||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||||
_pSdkManager(pSdkManager),
|
_pSdkManager(pSdkManager),
|
||||||
_succeedLastApply(true),
|
|
||||||
_pScene(pScene),
|
_pScene(pScene),
|
||||||
_curFbxNode(pScene->GetRootNode()),
|
_curFbxNode(pScene->GetRootNode()),
|
||||||
_currentStateSet(new osg::StateSet()),
|
_currentStateSet(new osg::StateSet()),
|
||||||
_lastMaterialIndex(0),
|
_lastMaterialIndex(0),
|
||||||
_lastMeshIndex(0),
|
_lastMeshIndex(0),
|
||||||
_options(options),
|
_options(options),
|
||||||
_externalWriter(srcDirectory, osgDB::getFilePath(fileName), true, 0)
|
_externalWriter(srcDirectory, osgDB::getFilePath(fileName), true, 0),
|
||||||
|
_texcoords(false),
|
||||||
|
_drawableNum(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
///Tell us if last Node succeed traversing.
|
|
||||||
bool succeedLastApply() const { return _succeedLastApply; }
|
|
||||||
|
|
||||||
///Set the flag _succeedLastApply to false.
|
|
||||||
void failedApply() { _succeedLastApply = false; }
|
|
||||||
|
|
||||||
virtual void apply(osg::Geode& node);
|
|
||||||
virtual void apply(osg::Geometry& node);
|
virtual void apply(osg::Geometry& node);
|
||||||
virtual void apply(osg::Group& node);
|
virtual void apply(osg::Group& node);
|
||||||
virtual void apply(osg::MatrixTransform& node);
|
virtual void apply(osg::MatrixTransform& node);
|
||||||
@ -195,9 +189,6 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
|||||||
|
|
||||||
private:
|
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().
|
* Fill the faces field of the mesh and call buildMesh().
|
||||||
* \param name the name to assign to the Fbx Mesh
|
* \param name the name to assign to the Fbx Mesh
|
||||||
@ -229,7 +220,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
|||||||
void createListTriangle(const osg::Geometry* geo,
|
void createListTriangle(const osg::Geometry* geo,
|
||||||
ListTriangle& listTriangles,
|
ListTriangle& listTriangles,
|
||||||
bool& texcoords,
|
bool& texcoords,
|
||||||
unsigned int& drawable_n);
|
unsigned int drawable_n);
|
||||||
|
|
||||||
///Store the material of the stateset in the MaterialMap.
|
///Store the material of the stateset in the MaterialMap.
|
||||||
int processStateSet(const osg::StateSet* stateset);
|
int processStateSet(const osg::StateSet* stateset);
|
||||||
@ -264,6 +255,12 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
|||||||
unsigned int _lastMeshIndex;
|
unsigned int _lastMeshIndex;
|
||||||
const osgDB::ReaderWriter::Options* _options;
|
const osgDB::ReaderWriter::Options* _options;
|
||||||
osgDB::ExternalFileWriter _externalWriter;
|
osgDB::ExternalFileWriter _externalWriter;
|
||||||
|
|
||||||
|
///Maintain geode state between visits to the geometry
|
||||||
|
GeometryList _geometryList;
|
||||||
|
ListTriangle _listTriangles;
|
||||||
|
bool _texcoords;
|
||||||
|
unsigned int _drawableNum;
|
||||||
};
|
};
|
||||||
|
|
||||||
// end namespace pluginfbx
|
// end namespace pluginfbx
|
||||||
|
Loading…
Reference in New Issue
Block a user