本系列文章部分内容来源于http://ogre3d.cn
的Ogre系列教程的中文翻译版,加上一些我自己学习时的笔记。Ogre三基石
SceneManager 场景管理器
屏幕上显示的所有东西都有场景管理器来管理。当往场景中添加物体时,场景管理器会记录物体的位置,当添加摄像机来观察某个场景时,场景管理器会记录摄像机的位置。Ogre里有多种场景管理器
Entity 实体
一个实体是可以在场景中渲染的物体之一。可以把实体理解为任何一个3D模型。一个机器人可以使一个实体,一条鱼可以是一个实体,大地草原可以是一个非常大的实体。
灯光,摄像机,粒子,广告牌等不能成为实体。 Ogre中你不能直接将一个实体放入场景中,而是将实体与场景节点绑在一起,这个场景节点则包括了实体的方位信息。
SceneNode 场景节点
场景节点将持续跟踪与它绑在一起的实体的方位。当你创建了一个实体时,它直到与一个场景节点绑定后才会被渲染。同样,一个场景节点也不能单独的在屏幕上显示出来,只有与一个实体绑定后才能在屏幕上显示。
一个场景节点可以绑定多个实体,场景节点同样可以和其他场景节点绑定,但是一个实体不能被多个场景节点绑定。 每个场景管理器都有一个根节点,而场景节点都是在根节点的基础上建立,其位置总是相对于根节点的。
实践
要创建一个实体,可以调用SceneManager的createEntity方法:
// 创建一个实体, 加载Athena网格。
Entity* entity1 = mSceneMgr->createEntity("athene1", "athene.mesh");
createEntity的第一个参数为实体指定了一个唯一的标识符,第二个参数表示要加载的资源名称,在这里是一个名为athene的网格模型。
我们可以为这个实体代表的网格模式指定一个材质:
// 设置网格材质。
entity1->setMaterialName("Examples/Athene/NormalMapped");
创建了一个实体后,还要创建一个场景节点与它绑定起来:
// 创建一个子场景节点。
SceneNode* node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("athene1");
与实体一样,场景节点的名字也是唯一的,在这里是athene1。
然后将实体和场景节点绑定:
// 将实体绑定到场景节点上。
node1->attachObject(entity1);
绑定之后实体就会被渲染出来,默认情况下实体会被渲染到世界坐标的原点(0, 0, 0)处。
要改变实体在场景中的位置,可以使用与之绑定的场景节点的setPosition方法:
node1->setPosition(30, 0, 0);
这样场景节点就相对于根节点往X轴正方向移动了10个单位。
同样,还可以使用场景节点的translate方法达到相同的目的:
node1->translate(Vector3(30, 0, 0));
setPosition位置的改变是相对于父节点的,translate则可以设置变换相对于哪个坐标系。
要得到场景节点的父节点,可以调用getParentNode:
SceneNode* parentNode = node1->getParentSceneNode();
要得到场景节点的名称,可以调用getName:
String nodeName = nod1->getName();
因为场景节点的移动都是相对于父节点的,所以很容易实现两个节点一起移动:
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的父节点,移动node1会使node2跟着一起移动,而移动node2不会影响node1。
缩放
使用场景节点可以对网格模型进行缩放:
node1->scale(1.5, 1.5, 1.5);
scale的三个参数分别对应x, y, z方向上的缩放比例,上面的例子将网格模型放大到1.5倍。
旋转
还可以对网格模型进行旋转,其中yaw是Y轴的旋转,pitch是X轴的旋转,roll是Z轴的旋转:
node1->yaw(Degree(-90));
node1->pitch(Degree(-90));
node1->roll(Degree(-90));