图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] ... 下一页 >>