图4.5若图片无法显示请联系QQ752018766
其中的 Vector3 (三文向量) 是 OGRE 向量类,它表示三文世界中的位置、方向和缩放因子。在头文件 OgreVector3.h 中定义,有若干重载:
Vector3 (Real fX, Real fY, Real fZ)
Vector3 (Real afCoordinate[3])
Vector3 (int afCoordinate[3])
Vector3 (const Real *const r)
Vector3 (const Vector3 &rkVector)
比如Vector3(0,0,0)表示坐标原点。
可看到函数设置旋转setRotation(const Quaternion& rot)的参数是四元数,四元数的形式可写成xi + yj + zk + w, i、j、k的平方都等于-1。
在头文件 OgreQuaternion.h 定义了四元数类,也有若干重载:
Quaternion (Real fW=1.0, Real fX=0.0, Real fY=0.0, Real fZ=0.0)
Quaternion (const Quaternion &rkQ)
Quaternion (const Matrix3 &rot)
// 由旋转矩阵构成的四元数
Quaternion (const Radian &rfAngle, const Vector3 &rkAxis)
// 由 角-轴 对构成的四元数
Quaternion (const Vector3 &xAxis, const Vector3 &yAxis, const Vector3 &zAxis) // 由三个正交轴构成的四元数
Quaternion (Vector3 *akAxis)
// 由三个正交轴构成的四元数
它也有两个预置四元数:
const Quaternion Quaternion::ZERO(0.0,0.0,0.0,0.0);
const Quaternion Quaternion::IDENTITY(1.0,0.0,0.0,0.0);
然后定义AnimationState类的对象,它和刚才定义的动画类相对应。设置动画的状态为启用:
mAnimState = mSceneMgr->createAnimationState("CameraTrack");
mAnimState->setEnabled(true);
// 启用该动画
到此,初始化工作就做完了。
要想使动画动起来,我们就要靠ExampleFrameListener了,它的主要作用是监听系统输入,并对场景做出控制反应。对于非控制性的变化(如自动的动画),其状态更新也可以由ExampleFrameListener完成。我们需要重载ExampleFrameLisener类的frameStarted函数, frameStarted和frameEnded是在每一帧渲染前后被调用的纯虚函数,ExampleFrameListener将实现这两个函数,以实现对场景物体的控制。
通过FrameLisener调用动画状态的addTime方法,可以完成动画状态的更新。另外,timeSinceLastFrame 是 Ogre:: FrameEvent 的数据成员,在头文件 OgreFrameListener.h 中定义,单位是秒:
Real Ogre::FrameEvent::timeSinceLastFrame
这个数据成员记录的是:上一次访问 FrameEvent::timeSinceLastFrame 属性到现在的时间差(秒)。因此我们可根据传入的时间来设置动画的状态。
调用函数mAnimState->addTime(evt.timeSinceLastFrame);
OGRE骨骼信息和动画信息保存到后缀名为.skeleton的文件中,你可以通过OGRE提供的导出插件工具(Milkshape和3Dmax的exporter)来导出该类型的文件。当你创建基于.Mesh文件的Entity时,.Skeleton文件将会自动被系统加载进来。为了操作方便,Entity自动给每一个动作指定一个AnimationState类(请参考基本动画)的对象,你可以通过Entity::getAnimationState函数来得到具体的动作。若图片无法显示请联系QQ752018766
实例:
图4.6
该实例创建基于robot.mesh文件的实体(Entity)对象,指定其。走。动作(动作信息都在.skeleton文件里),并将其显示到屏幕上。robot.mesh文件中保存机器人的网格信息,Entity会自动加载保存有机器人骨骼信息的robot.skeleton文件。我们重载ExampleApplication类的createScene函数,其关键部分代码如下:
void createScene(void)
{
// 设置关键帧之间的插值方法为样条插值
Animation::setDefaultInterpolationMode(Animation::IM_SPLINE);
// 创建基于网格文件robot.mesh的Entity
Entity *ent = mSceneMgr->createEntity(robot, robot.mesh);
// 将实体附属到场景根结点上
mSceneMgr->getRootSceneNode()->createChild()->attachObject(ent);
// 得到实体走动作的AnimationState类对象
mAnimState = ent->getAnimationState(Walk);
// Enable。(起始)该动作
mAnimState->setEnabled(true);
}
在createScene函数里成功的指定了机器人的当前动作为走,下一步要让动画动起来,还需要根据时间跨度计算当前帧的骨骼位置。重载ExampleFrameListener类的frameStarted函数:
bool frameStarted(const FrameEvent& evt)
{
// 将两帧之间的时间差传入AnimationState::addTime函数,该函数内部会计算出动画的当前时间点。
mAnimState->addTime(evt.timeSinceLastFrame);
// 调用父类的frameStarted函数
return ExampleFrameListener::frameStarted(evt);
}
在CameraTrack工程的基础上,我加入了一个忍者跳跃和一个女侠拍手的动画,如图所示若图片无法显示请联系QQ752018766
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >>