OSG中新增多個物體, OSG::Group的使用
阿新 • • 發佈:2019-02-16
之前的文章可以針對單個物體,進行平移,旋轉,縮放。
現在我想在場景中放置兩頭牛。在OSG中,放置多個物體,可以將這個多個物體放置到一個Group中,然後再將場景設定成這個Group,就可以了。
正常使用是這樣的,由於Group繼承自Node,所以可以把 Group* 作為引數,傳遞給viewer.setScenData。#include<osgViewer/Viewer> #include<osgDB/ReadFile> int main(int argc, char **argv) { osgViewer::Viewer viewer; osg::Node *cow1 = osgDB::readNodeFile("cow.osg"); osg::Node *cow2 = osgDB::readNodeFile("cow.osg"); osg::Group *root = new osg::Group; root->addChild(cow1); root->addChild(cow2); //把牛放到場景中 viewer.setSceneData(root); return viewer.run(); }
但是程式執行結果只顯示了一頭牛。猜測是兩頭牛重疊了,把其中的一頭牛挪一下位置,試試。挪位置,用MatrixTransform。
上面的程式比之前第一個程式多了3行程式碼,建立一個MatrixTransform,然後把cow2放在了MatrixTransform下面。#include<osgViewer/Viewer> #include<osgDB/ReadFile> #include <osg/MatrixTransform> int main(int argc, char **argv) { osgViewer::Viewer viewer; osg::Node *cow1 = osgDB::readNodeFile("cow.osg"); osg::Node *cow2 = osgDB::readNodeFile("cow.osg"); osg::MatrixTransform* translateMT = new osg::MatrixTransform; translateMT->setMatrix(osg::Matrix::translate(10, 0, 0)); translateMT->addChild(cow2); osg::Group *root = new osg::Group; root->addChild(cow1); root->addChild(translateMT); //把牛放到場景中 viewer.setSceneData(root); return viewer.run(); }
修改了一行程式碼, root->addChild(cow2) 修改成了 root->addChild(translateMT)。
這個程式的執行結果如下。
成功的顯示了兩頭牛。
這都要歸功於osg::Group。現在來看一下osg::Group這個類。osg::Group這個類其實就是一個Node的列表,裡面可以儲存多個Node,然後它本身繼承自Node,可以當成一個Node來使用。下面是它的類圖,其中NodeList的型別為 typedef std::vector< ref_ptr<Node> > NodeList; 這就是一個std::vector,其中vector裡面的元素為ref_ptr<Node>,相當於Node*,只是多了個引用計數。
簡單的,我們可以把Group看成是Node的集合,但是又可以把Group當成Node來使用。
其實這裡使用了設計模式中的組合(COMPOSITE)模式。組合模式有兩個要點,一是子類繼承自父類, 二是子類有父類的指標列表。
這樣的話,子類可以把多個父類 組合在一起,而且子類又可以當成父類來使用。
再看上面的程式碼,我覺得cow1和cow2都是讀取自"cow.osg",可不可以只讀一遍呢?其實是可以的,下面的程式碼也能正常執行。
#include<osgViewer/Viewer>
#include<osgDB/ReadFile>
#include <osg/MatrixTransform>
int main(int argc, char **argv)
{
osgViewer::Viewer viewer;
osg::Node *cow = osgDB::readNodeFile("cow.osg");
osg::MatrixTransform* translateMT = new osg::MatrixTransform;
translateMT->setMatrix(osg::Matrix::translate(10, 0, 0));
translateMT->addChild(cow);
osg::Group *root = new osg::Group;
root->addChild(cow);
root->addChild(translateMT);
//把牛放到場景中
viewer.setSceneData(root);
return viewer.run();
}
同樣顯示了兩頭牛。所以,OSG中要新增多個物體,就使用osg::Group就可以了,每個物體都新增到Group中,當然需要對一些物體進行平移,以免物體重疊到一起了。