旋转的摄像头

这几天熟悉了一下Entity,SceneManager,SceneNode。自己可以简单的实现了站立的robot和ninja,总感觉静态的场景不好玩,想做一下动态的场景,由于本人目前是初学者,所以也就只能做做关键帧动画,骨骼动画就留在后面实现吧,hoho~

 

定义一个10秒种的动画,这个动画包含一个动画轨迹(上下翻转)。让这个动画应用到当前摄像机上去,程序运行时,我(第一人称摄像机)应该在上下翻转。

 

       在createScene函数里做初始化工作。

       首先我们考虑怎样可以把动画应用到当前摄像机上。因为一个动画可以应用到一个节点上,所以可以创   建一个节点并将当前摄像机attach到这个节点上去,代码如下:

        SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChild();

        camNode->attachObject(mCamera);

 

       下面定义动画、动画轨迹以及关键帧:

        // 定义动画,指定动画的名称及长度(这里为10秒)

        Animation* anim = mSceneMgr->createAnimation("CameraTrack", 10);

        // 指定动画关键帧之间的插值方式(包括线性插值和样条插值)

         anim->setInterpolationMode(Animation::IM_SPLINE);

        // 定义动画的一个动画轨迹,并指定这个轨迹是作用到camNode节点上的

        AnimationTrack* track = anim->createTrack(0, camNode);

        // 定义动画轨迹包含的关键帧,下面定义了四个关键帧,加上起始帧

              // 五个关健帧形成了一个翻转的动画。

        KeyFrame* key = track->createKeyFrame(0); // startposition

        key = track->createKeyFrame(2.5);

        key->setTranslate(Vector3(500,500,-1000));

        key = track->createKeyFrame(5);

        key->setTranslate(Vector3(-1500,1000,-600));

        key = track->createKeyFrame(7.5);

        key->setTranslate(Vector3(0,-100,0));

        key = track->createKeyFrame(10);

        key->setTranslate(Vector3(0,0,0));             

 

       然后定义AnimationState类的对象,它和刚才定义的动画类相对应。设置动画的状态为启用:

        mAnimState = mSceneMgr->createAnimationState("CameraTrack");

        mAnimState->setEnabled(true);     // 启用该动画

       到此,初始化工作就做完了.

 

最后,要想使动画动起来,我们需要重载ExampleFrameLisener类的frameStarted函数,并调用下面的函数,根据传入的时间来设置动画的状态:    mAnimState->addTime(evt.timeSinceLastFrame);

 

以下是进行重载ExampleFrameLisener类的frameStarted函数的操作。

#include "ExampleFrameListener.h"
AnimationState *mAnimState;
class ProjectiveDecalListener : public ExampleFrameListener
{
public:
 ProjectiveDecalListener(RenderWindow* win, Camera* cam)
  : ExampleFrameListener(win, cam)
 {

 }

 ~ProjectiveDecalListener()
 {

 }

 bool frameStarted(const FrameEvent& evt)
 {
  mAnimState->addTime(evt.timeSinceLastFrame);
  return ExampleFrameListener::frameStarted(evt);  //没有这句的话,鼠标和键盘将无法控制

 }

};

 

重载ExampleApplication类中的createFrameListener函数,可以放在CreateScene()的后面。

 void createFrameListener(void)
 {
  mFrameListener= new ProjectiveDecalListener(mWindow, ExampleApplication::mCamera);
  mRoot->addFrameListener(mFrameListener);
 }

 这里需要对上面这个函数进行详细的讲解:

因为Root类是要每帧更新的,他也了解FrameListeners。我们首先要创建ProjectiveDecalListener的实例,然后把他注册到Root对象中。

mRoot和mFrameListener变量是在ExampleApplication类中定义的。addFrameListener方法添加一个帧监听者,removeFrameListener方法移除帧监听者(也就是说FrameListener就不用在更新了)。注意add|removeFrameListener方法仅仅是得到一个指向FrameListener的指针(也就是说FrameListener并没有一个名字你可以移除她)。这就意味着你需要对每一个FrameListener持有一个指针,让你随后可以移除他们。


 这样我们就可以看到旋转摄像头里所看到的场景图像了。

 

 

 

你可能感兴趣的:(vector,animation,化工,IM,CAM)