Ogre中的SceneNode节点

来源:互联网 发布:c语言bmp转化为灰度图 编辑:程序博客网 时间:2024/06/07 06:50

SceneManager场景管理器,管理啥呢?管理的就是Node,具体点是SceneNode

SceneNode继承自Node,Node只是个虚类,定义了很大一部分操作和接口

SceneNode和Node之间是代码重用关系,不是接口关系。(例如SceneNode提供了attachObject函数,而Node没有提供这个接口)。所以不要指望用Node的指针操作所有SceneNode的操作。应该直接用SceneNode的指针。Node存在的目的是减少代码的重复编写。这虽然是继承最普通的用法,但是在设计模式之帝Ogre里看到这种代码多少会迷糊点,我以为它又要用什么神奇的设计模式了。


那这样,就必须得先看Node了

OgreNode.h

定义了Node类,你可以把这个类理解成纯粹是一个树上的节点。这个类完成的功能主要包括:定义了节点之间的树结构,而且还实现了事件监听(例如添加个Node到树触发什么什么的)

关于属性(为啥我要以属性来分析功能,而不是以函数?很容易啊~~~又不是算法类,实体类的每个函数都是设置或者获取属性值的,只是方法不同而已,所以属性值基本可以清楚的代表一切了)

首先必须是树结构的信息:包括父节点和子节点集合,已经一些标志(标志啥?更新啊。本节点变化,所有子节点得跟着变化吧,父节点变化,都得变吧)

然后是节点的信息:

包括朝向、位置和放大:mOrientation:Quaternion,mPosistion:Vector3, mScale:Vector3。要注意的是,这里的朝向和位置都是相对于父节点的

包含从父节点继承的朝向、位置和放大

包含作为关键帧动画的起始朝向、位置和放大

也就这么点东西了。

然后是

OgreSceneNode.h

这个就主要和场景有关了。

场景上需要除了树之外的什么东西呢?

要能显示一个WireBoundingBox吧?不过不是必须的,但是Ogre提供了。mWireBoundingBox: WireBoundingBox

既然是场景里的,场景管理器SceneManager肯定要有个指针吧,毕竟是人家创造的。mCreator:SceneManager,还得有个bool判定是否加进了SceneManager里了

场景里就有碰撞检测的需求,那就要有AABB啦~~~mWorldAABB:AxisAlignedBox

另外,增强了点功能,例如Node里提供的yaw操作只能绕着y轴转,但是SceneNode里扩展到了可以绕任意轴

另外既然是可显示的节点,那就得能选择这个节点显示不显示。有个bool值

另外扩展了一个功能,就是一个节点可以根据另外一个节点自动的改变自己的位置和朝向。


下面要说操作,在这之前,必须要讲一个概念,就是Node里存放的节点位置和朝向都是相对于父节点的。那么他们的函数操作就分为相对于父节点坐标系、或者是自己本身的局部坐标系和世界坐标系两种。有个Enum定义了这三种坐标系,分别为TS_LOCAL, TS_PARENT, TS_WORLD

在Node的translate函数里,可以设置到底是哪种。

另外你想啊,你定义一个子节点,那个节点的坐标系会和父节点一样?这个确实很复杂。

既然子节点的Orientation是相对于父节点的。也就是说子节点的坐标系的方向就是父节点的朝向(通常用z轴限定)。那么可不可以更改子节点的坐标系朝向?当然可以啊,用setDirection函数,这样的话它的mOrientation参数就肯定得跟着变了,毕竟,虽然说子节点是相对于父节点的,那是说的坐标系。子节点存储的Orientation值还是相当于本节点的。那这样岂不是与父节点的朝向信息失去联系了?木有,别忘了Node里还有存放父节点朝向的地方呢~~~~其实,存放父节点朝向的信息是从父节点的父节点迭代计算下来的,其实最后就是相对于根节点的Orientation。

发现问题的关键了麽?如果你改了坐标系的朝向,但是节点在根节点的总坐标系中确仍然是根据父节点*mOriention计算出来的,也就是说,改坐标系的朝向就相当于改了那面是正面,哪面是反面。或者其他坐标轴。(比如改成了屁股是正面),就是用的setDirection函数,或者lookAt函数。