diff --git a/src/osgPlugins/fbx/WriterNodeVisitor.cpp b/src/osgPlugins/fbx/WriterNodeVisitor.cpp index d3c47bdbf..eae2a1153 100644 --- a/src/osgPlugins/fbx/WriterNodeVisitor.cpp +++ b/src/osgPlugins/fbx/WriterNodeVisitor.cpp @@ -468,7 +468,7 @@ WriterNodeVisitor::setControlPointAndNormalsAndUV(const GeometryList& geometryLi for (MapIndices::iterator it = index_vert.begin(); it != index_vert.end(); ++it) { - const osg::Geometry* pGeometry = geometryList[it->first.drawableIndex]; + const osg::Geometry* pGeometry = geometryList[it->first.drawableIndex]; unsigned int vertexIndex = it->first.vertexIndex; unsigned int normalIndex = it->first.normalIndex; @@ -603,7 +603,7 @@ void WriterNodeVisitor::buildFaces(const std::string& name, void WriterNodeVisitor::createListTriangle(const osg::Geometry* geo, ListTriangle& listTriangles, bool& texcoords, - unsigned int& drawable_n) + unsigned int drawable_n) { unsigned int nbVertices = 0; { @@ -638,65 +638,32 @@ 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) { - // 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() + // here we simply create a single fbx node to assign it the mesh + // retrieved from the geometry. - // 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; + // 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()); + _geometryList.push_back(&geometry); - // return to parent fbx node - _curFbxNode = parent; + pushStateSet(geometry.getStateSet()); + 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 + _curFbxNode = parent; } - void WriterNodeVisitor::apply(osg::Group& node) { 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()); _curFbxNode->AddChild(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); + + if (_listTriangles.size() > 0) + buildFaces(node.getName(), _geometryList, _listTriangles, _texcoords); + _curFbxNode = parent; } @@ -734,30 +714,5 @@ 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 } diff --git a/src/osgPlugins/fbx/WriterNodeVisitor.h b/src/osgPlugins/fbx/WriterNodeVisitor.h index 6e0ae7b9a..b0b72ada1 100644 --- a/src/osgPlugins/fbx/WriterNodeVisitor.h +++ b/src/osgPlugins/fbx/WriterNodeVisitor.h @@ -78,23 +78,17 @@ class WriterNodeVisitor: public osg::NodeVisitor const std::string& srcDirectory) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _pSdkManager(pSdkManager), - _succeedLastApply(true), _pScene(pScene), _curFbxNode(pScene->GetRootNode()), _currentStateSet(new osg::StateSet()), _lastMaterialIndex(0), _lastMeshIndex(0), _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::Group& node); virtual void apply(osg::MatrixTransform& node); @@ -195,9 +189,6 @@ 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 name the name to assign to the Fbx Mesh @@ -229,7 +220,7 @@ class WriterNodeVisitor: public osg::NodeVisitor void createListTriangle(const osg::Geometry* geo, ListTriangle& listTriangles, bool& texcoords, - unsigned int& drawable_n); + unsigned int drawable_n); ///Store the material of the stateset in the MaterialMap. int processStateSet(const osg::StateSet* stateset); @@ -264,6 +255,12 @@ class WriterNodeVisitor: public osg::NodeVisitor unsigned int _lastMeshIndex; const osgDB::ReaderWriter::Options* _options; osgDB::ExternalFileWriter _externalWriter; + + ///Maintain geode state between visits to the geometry + GeometryList _geometryList; + ListTriangle _listTriangles; + bool _texcoords; + unsigned int _drawableNum; }; // end namespace pluginfbx