查看: 1457|回复: 4

遍历FBX模型节点时,奇慢无比!

[复制链接]

该用户从未签到

发表于 2013-5-23 15:15:02 | 显示全部楼层 |阅读模式
本帖最后由 code_ming 于 2013-5-23 15:16 编辑

我已经可以正常加载FBX模型了,我的模型是机械模型,我用的是海军教程中遍历节点的方式来获取我需要的节点,最后能获取到最终节点,然后奇慢无比,我导出ive和osg格式,也是很慢,求指教!贴上代码!
FindNodeVisitor.h
  1. #ifndef FIND_NODE_VISITOR_H
  2. #define FIND_NODE_VISITOR_H

  3. #include <osg/Geode>
  4. #include <osg/NodeVisitor>
  5. #include <osg/Node>
  6. #include <osg/Transform>
  7. #include <osgSim/DOFTransform>
  8. #include <iostream>
  9. #include <vector>

  10. class FindNodeVisitor : public osg::NodeVisitor
  11. {
  12. public:

  13.    FindNodeVisitor();

  14.    FindNodeVisitor(const std::string &searchName) ;

  15.    virtual void apply(osg::Node &searchNode);
  16.    virtual void apply(osg::Transform &searchNode);
  17.    virtual void apply(osg::Geode &geode);

  18.    void setNameToFind(const std::string &searchName);

  19.    osg::Node* getFirst();

  20.    typedef std::vector<osg::Node*> nodeListType;

  21.    nodeListType& getNodeList() { return foundNodeList; }

  22. private:

  23.    std::string searchForName;
  24.    nodeListType foundNodeList;

  25. };

  26. #endif

复制代码
FindNodeVisitor.cpp

  1. #include "stdafx.h"
  2. #include "findNodeVisitor.h"

  3. // Default constructor - initialize searchForName to "" and
  4. // set the traversal mode to TRAVERSE_ALL_CHILDREN
  5. FindNodeVisitor::FindNodeVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
  6.         searchForName()
  7. {
  8. }

  9. // Constructor that accepts string argument
  10. // Initializes searchForName to user string
  11. // set the traversal mode to TRAVERSE_ALL_CHILDREN
  12. FindNodeVisitor::FindNodeVisitor(const std::string &searchName) :
  13. osg::NodeVisitor(TRAVERSE_ALL_CHILDREN),
  14.         searchForName(searchName)
  15. {
  16. }

  17. //The 'apply' method for 'node' type instances.
  18. //Compare the 'searchForName' data member against the node's name.
  19. //If the strings match, add this node to our list
  20. void FindNodeVisitor::apply(osg::Node &searchNode)
  21. {
  22.         if (searchNode.getName() == searchForName)
  23.         {
  24.                 foundNodeList.push_back(&searchNode);
  25.         }
  26.         traverse(searchNode);
  27. }

  28. // Set the searchForName to user-defined string
  29. void FindNodeVisitor::setNameToFind(const std::string &searchName)
  30. {
  31.         searchForName = searchName;
  32.         foundNodeList.clear();
  33. }

  34. void FindNodeVisitor::apply(osg::Transform &searchNode)
  35. {
  36.         apply ( (osg::Node&) searchNode);
  37.         traverse(searchNode);
  38. }
  39. void FindNodeVisitor::apply(osg::Geode &geode)
  40. {
  41.         apply((osg::Node&)geode);
  42.         traverse((osg::Node&)geode);
  43. }
  44. osg::Node* FindNodeVisitor::getFirst()
  45. {
  46.         return *(foundNodeList.begin());
  47. }
复制代码
测试程序:

  1. // 3DVRTest.cpp : 定义控制台应用程序的入口点。
  2. //

  3. #include "stdafx.h"
  4. #include "findNodeVisitor.h"

  5. #include <osgViewer/Viewer>
  6. #include <osg/Node>
  7. #include <osg/Geode>
  8. #include <osg/Group>
  9. #include <osgDB/ReadFile>
  10. #include <osgDB/WriteFile>
  11. #include <osgUtil/Optimizer>
  12. #include "string"

  13. int _tmain(int argc, _TCHAR* argv[])
  14. {
  15.         osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
  16.         osg::ref_ptr<osg::Group> root = new osg::Group();
  17.         osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("zhijia.fbx");
  18.         /*FindNodeVisitor zhijia("dizuo08");
  19.         node->accept(zhijia);
  20.         if(!zhijia.getFirst())
  21.         {
  22.                 std::cout<<"无法找到节点,查找失败"<<std::endl;
  23.         }
  24.         else
  25.         {
  26.                 std::cout<<"查找节点成功,成功找到节点"<<std::endl;
  27.         }*/
  28.         root->addChild(node.get());
  29.         osgUtil::Optimizer optimizer;
  30.         optimizer.optimize(node.get());
  31.         optimizer.reset();
  32.         viewer->setSceneData(root.get());
  33.         viewer->realize();
  34.         viewer->run();
  35.         return 0;
  36. }
复制代码

该用户从未签到

发表于 2013-5-23 15:23:14 | 显示全部楼层
  1. void FindNodeVisitor::apply(osg::Transform &searchNode)
  2. {
  3.         apply ( (osg::Node&) searchNode);
  4.         traverse(searchNode);
  5. }
  6. void FindNodeVisitor::apply(osg::Geode &geode)
  7. {
  8.         apply((osg::Node&)geode);
  9.         traverse((osg::Node&)geode);
  10. }
复制代码
这段代码不需要,并且里面又traverse了 就对子场景遍历了两次

该用户从未签到

 楼主| 发表于 2013-5-23 16:46:27 | 显示全部楼层
liuzhiyu123 发表于 2013-5-23 15:23
这段代码不需要,并且里面又traverse了 就对子场景遍历了两次

多谢,经尝试时间确实缩短了很多,但是还是用了8秒多少,还有木有可以优化的地方,或者用其他方式来获取我需要的节点?请指教!

该用户从未签到

发表于 2013-5-23 16:52:29 | 显示全部楼层
能确定要找到的节点是什么类型的可以加快 直接重载相应的apply函数 这样就省去了 每个Node都进行判断的时间

该用户从未签到

发表于 2013-5-23 16:53:33 | 显示全部楼层
如果确实是操作太多,放到thread里面去访问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表