生活随笔
收集整理的這篇文章主要介紹了
如何知道osg模型每个节点的名称
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題的提出:
有時我們需要按節點名稱找出模型中的節點,例如如下代碼:
class findNodeVisitor : public osg::NodeVisitor
{public:findNodeVisitor();findNodeVisitor(const std::string &searchName);virtual void apply(osg::Node &searchNode);virtual void apply(osg::Transform &searchNode);void setNameToFind(const std::string &searchName);osg::Node* getFirst();typedef std::vector<osg::Node*> nodeListType;nodeListType& getNodeList() { return foundNodeList; }private:std::string searchForName;nodeListType foundNodeList;};findNodeVisitor::findNodeVisitor() : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), searchForName()
{}findNodeVisitor::findNodeVisitor(const std::string &searchName) : osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), searchForName(searchName)
{}void findNodeVisitor::setNameToFind(const std::string &searchName)
{searchForName = searchName;foundNodeList.clear();}osg::Node* findNodeVisitor::getFirst()
{return *(foundNodeList.begin());}void findNodeVisitor::apply(osg::Node &searchNode)
{if (searchNode.getName() == searchForName){foundNodeList.push_back(&searchNode);}traverse(searchNode);
}void findNodeVisitor::apply(osg::Transform &searchNode)
{osgSim::DOFTransform* dofNode =dynamic_cast<osgSim::DOFTransform*> (&searchNode);if (dofNode){dofNode->setAnimationOn(false);}apply((osg::Node&) searchNode);traverse(searchNode);}
int main()
{// 初始化變量和模型,建立場景osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();osg::ref_ptr<osg::Group> root = new osg::Group();osg::ref_ptr<osg::Node> tankNode = osgDB::readNodeFile("d:\\1.OSGB");root->addChild(tankNode.get());findNodeVisitor findGun("gun"); root->accept(findGun);//優化場景數據osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//設置場景數據viewer->setSceneData(root.get());//初始化并創建窗口viewer->realize();//開始渲染viewer->run();return 0;}
在上面的代碼段main函數中的如下代碼:
?findNodeVisitor findGun("gun");?
中的”gun“表示按節點名稱來查找,只找模型中名稱為"gun"的節點,有時我們從3D建模人員拿到的模型文件他們也不記得模型中各個節點的名稱了,那我們怎么辦呢?我們可以用如下代碼枚舉出模型中的每個節點的名稱、庫名、類名,如下:
#include <iostream>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/NodeVisitor>
#include <osg/Node>
#include <osg/Group>
#include <osgSim/DOFTransform>
#include <osgUtil/Optimizer>
#include <osg/NodeVisitor>
#include <iostream>
#include <vector>
#include <codecvt>
#include <locale>
using namespace std;
#ifdef WIN32
#include<Windows.h>
#endifstring Utf8ToGB2312(const std::string& strUtf8)
{std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8;std::wstring wTemp = cutf8.from_bytes(strUtf8);
#ifdef _MSC_VERstd::locale loc("zh-CN");
#elsestd::locale loc("zh_CN.GB18030");
#endifconst wchar_t* pwszNext = nullptr;char* pszNext = nullptr;mbstate_t state = {};std::vector<char> buff(wTemp.size() * 2);int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> >(loc).out(state,wTemp.data(), wTemp.data() + wTemp.size(), pwszNext,buff.data(), buff.data() + buff.size(), pszNext);if (std::codecvt_base::ok == res){return std::string(buff.data(), pszNext);}return "";
}
class InfoVisitor : public osg::NodeVisitor
{
public:InfoVisitor():osg::NodeVisitor(TRAVERSE_ALL_CHILDREN), _indent(0){}virtual void apply(osg::Node& node){for (int i = 0; i < _indent; i++) cout << " ";cout << "[" << _indent << "]" << node.libraryName()<< "::" << node.className() << "----" << Utf8ToGB2312(node.getName()) << endl;_indent++;traverse(node);_indent--;for (int i = 0; i < _indent; i++) cout << " ";cout << "[" << _indent << "] " << node.libraryName()<< "::" << node.className() << "----" << Utf8ToGB2312(node.getName()) << endl;}virtual void apply(osg::Geode& node){for (int i = 0; i < _indent; i++) cout << " ";cout << "[" << _indent << "] " << node.libraryName()<< "::" << node.className() << "----" << Utf8ToGB2312(node.getName()) << endl;_indent++;for (unsigned int n = 0; n < node.getNumDrawables(); n++){osg::Drawable* draw = node.getDrawable(n);if (!draw)continue;for (int i = 0; i < _indent; i++) cout << " ";cout << "[" << _indent << "]" << draw->libraryName() << "::"<< draw->className() << "----" << Utf8ToGB2312(node.getName()) << endl;}traverse(node);_indent--;for (int i = 0; i < _indent; i++) cout << " ";cout << "[" << _indent << "]" << node.libraryName()<< "::" << node.className() << "----" << Utf8ToGB2312(node.getName()) << endl;}private:int _indent;
};
int main()
{// 初始化變量和模型,建立場景osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();osg::ref_ptr<osg::Group> root = new osg::Group();osg::ref_ptr<osg::Node> tankNode = osgDB::readNodeFile("d:\\1.OSGB");root->addChild(tankNode.get());InfoVisitor infoVisitor;if (root){root->accept(infoVisitor);}//優化場景數據osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//設置場景數據viewer->setSceneData(root.get());//初始化并創建窗口viewer->realize();//開始渲染viewer->run();return 0;}
注意:上述的node.getName()即節點名稱要用Utf8ToGB2312函數轉換一下,否則對于中文的名稱會出現亂碼。運行截圖如下:
參考鏈接:OSG節點訪問和遍歷 - adyzng - 博客園 (cnblogs.com)
總結
以上是生活随笔為你收集整理的如何知道osg模型每个节点的名称的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。