本系列文章部分內(nèi)容來源于http://ogre3d.cn
的Ogre系列教程的中文翻譯版,加上一些我自己學(xué)習(xí)時(shí)的筆記。Ogre三基石
SceneManager 場景管理器
屏幕上顯示的所有東西都有場景管理器來管理。當(dāng)往場景中添加物體時(shí),場景管理器會記錄物體的位置,當(dāng)添加攝像機(jī)來觀察某個(gè)場景時(shí),場景管理器會記錄攝像機(jī)的位置。Ogre里有多種場景管理器
Entity 實(shí)體
一個(gè)實(shí)體是可以在場景中渲染的物體之一。可以把實(shí)體理解為任何一個(gè)3D模型。一個(gè)機(jī)器人可以使一個(gè)實(shí)體,一條魚可以是一個(gè)實(shí)體,大地草原可以是一個(gè)非常大的實(shí)體。
燈光,攝像機(jī),粒子,廣告牌等不能成為實(shí)體。 Ogre中你不能直接將一個(gè)實(shí)體放入場景中,而是將實(shí)體與場景節(jié)點(diǎn)綁在一起,這個(gè)場景節(jié)點(diǎn)則包括了實(shí)體的方位信息。
SceneNode 場景節(jié)點(diǎn)
場景節(jié)點(diǎn)將持續(xù)跟蹤與它綁在一起的實(shí)體的方位。當(dāng)你創(chuàng)建了一個(gè)實(shí)體時(shí),它直到與一個(gè)場景節(jié)點(diǎn)綁定后才會被渲染。同樣,一個(gè)場景節(jié)點(diǎn)也不能單獨(dú)的在屏幕上顯示出來,只有與一個(gè)實(shí)體綁定后才能在屏幕上顯示。
一個(gè)場景節(jié)點(diǎn)可以綁定多個(gè)實(shí)體,場景節(jié)點(diǎn)同樣可以和其他場景節(jié)點(diǎn)綁定,但是一個(gè)實(shí)體不能被多個(gè)場景節(jié)點(diǎn)綁定。 每個(gè)場景管理器都有一個(gè)根節(jié)點(diǎn),而場景節(jié)點(diǎn)都是在根節(jié)點(diǎn)的基礎(chǔ)上建立,其位置總是相對于根節(jié)點(diǎn)的。
實(shí)踐
要創(chuàng)建一個(gè)實(shí)體,可以調(diào)用SceneManager的createEntity方法:
// 創(chuàng)建一個(gè)實(shí)體, 加載Athena網(wǎng)格。
Entity* entity1 = mSceneMgr->createEntity("athene1", "athene.mesh");
createEntity的第一個(gè)參數(shù)為實(shí)體指定了一個(gè)唯一的標(biāo)識符,第二個(gè)參數(shù)表示要加載的資源名稱,在這里是一個(gè)名為athene的網(wǎng)格模型。
我們可以為這個(gè)實(shí)體代表的網(wǎng)格模式指定一個(gè)材質(zhì):
// 設(shè)置網(wǎng)格材質(zhì)。
entity1->setMaterialName("Examples/Athene/NormalMapped");
創(chuàng)建了一個(gè)實(shí)體后,還要創(chuàng)建一個(gè)場景節(jié)點(diǎn)與它綁定起來:
// 創(chuàng)建一個(gè)子場景節(jié)點(diǎn)。
SceneNode* node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("athene1");
與實(shí)體一樣,場景節(jié)點(diǎn)的名字也是唯一的,在這里是athene1。
然后將實(shí)體和場景節(jié)點(diǎn)綁定:
// 將實(shí)體綁定到場景節(jié)點(diǎn)上。
node1->attachObject(entity1);
綁定之后實(shí)體就會被渲染出來,默認(rèn)情況下實(shí)體會被渲染到世界坐標(biāo)的原點(diǎn)(0, 0, 0)處。
要改變實(shí)體在場景中的位置,可以使用與之綁定的場景節(jié)點(diǎn)的setPosition方法:
node1->setPosition(30, 0, 0);
這樣場景節(jié)點(diǎn)就相對于根節(jié)點(diǎn)往X軸正方向移動了10個(gè)單位。
同樣,還可以使用場景節(jié)點(diǎn)的translate方法達(dá)到相同的目的:
node1->translate(Vector3(30, 0, 0));
setPosition位置的改變是相對于父節(jié)點(diǎn)的,translate則可以設(shè)置變換相對于哪個(gè)坐標(biāo)系。
要得到場景節(jié)點(diǎn)的父節(jié)點(diǎn),可以調(diào)用getParentNode:
SceneNode* parentNode = node1->getParentSceneNode();
要得到場景節(jié)點(diǎn)的名稱,可以調(diào)用getName:
String nodeName = nod1->getName();
因?yàn)閳鼍肮?jié)點(diǎn)的移動都是相對于父節(jié)點(diǎn)的,所以很容易實(shí)現(xiàn)兩個(gè)節(jié)點(diǎn)一起移動:
Entity *entity1 = mSceneMgr->createEntity( "Athene1", "Athene.mesh" );
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "AtheneNode1" );
ode1->attachObject( entity1 );
Entity *entity2 = mSceneMgr->createEntity( "Athene2", "Athene.mesh" );
SceneNode *node2 = node1->createChildSceneNode( "AtheneNode2", Vector3( 50, 0, 0 ) );
node2->attachObject( entity2 );
這樣一來,node1就成了node2的父節(jié)點(diǎn),移動node1會使node2跟著一起移動,而移動node2不會影響node1。
縮放
使用場景節(jié)點(diǎn)可以對網(wǎng)格模型進(jìn)行縮放:
node1->scale(1.5, 1.5, 1.5);
scale的三個(gè)參數(shù)分別對應(yīng)x, y, z方向上的縮放比例,上面的例子將網(wǎng)格模型放大到1.5倍。
旋轉(zhuǎn)
還可以對網(wǎng)格模型進(jìn)行旋轉(zhuǎn),其中yaw是Y軸的旋轉(zhuǎn),pitch是X軸的旋轉(zhuǎn),roll是Z軸的旋轉(zhuǎn):
node1->yaw(Degree(-90));
node1->pitch(Degree(-90));
node1->roll(Degree(-90));