1. 程式人生 > >OSG中新增多個物體, OSG::Group的使用

OSG中新增多個物體, OSG::Group的使用

之前的文章可以針對單個物體,進行平移,旋轉,縮放。

現在我想在場景中放置兩頭牛。在OSG中,放置多個物體,可以將這個多個物體放置到一個Group中,然後再將場景設定成這個Group,就可以了。

#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();
}
正常使用是這樣的,由於Group繼承自Node,所以可以把 Group* 作為引數,傳遞給viewer.setScenData。

但是程式執行結果只顯示了一頭牛。猜測是兩頭牛重疊了,把其中的一頭牛挪一下位置,試試。挪位置,用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();
}
上面的程式比之前第一個程式多了3行程式碼,建立一個MatrixTransform,然後把cow2放在了MatrixTransform下面。

修改了一行程式碼, 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中,當然需要對一些物體進行平移,以免物體重疊到一起了。