Ogre基本动画实例

 

通过上一章的介绍,假设你已经知道如何用Ogre的 项目向导初步建立了一个可以执行的3D程序,这个3D程序就是显示一个Ogre的头像。那么我们就可以学习下面的东西了。注意,在看我的文章前,最好还是去http://ogre3d.cn看一下该引擎的基本教程,虽然我的都是基本教程,但是,我的没那网站的教程说的详细,我的只是学习过程中的一些笔记而已,那些是基本功课,必须学习一下的。

在开始之前,我同样要申明一下的,以后我就不在复述了:我的许多代码都是以过程级进行添加的很少会在原来的基础上加上去的,除非加上去的东西是和原来的代码有密切关系。那样我们就会对每一部分代码有很清晰的划分,其实这也是我写代码的习惯,希望大家都养成良好的习惯吧。

正题:

       定义一个10秒种的动画,这个动画包含一个动画轨迹(上下翻转)。让这个动画应用到当前摄像机上去,程序运行时,我(第一人称摄像机)应该在上下翻转。
1、先定义一个动画对象,AnimationState* mAnimState;把这个代码写在所有的代码前面吧,那样在这个单元中可以用到它。
2、程序向导已经为我们自动创建了摄像机,(在virtual void createCamera(void)过程中)
3、我们建立一个过程,代码如下:(创建动画)
    void CreateAnimation()
    
...{
        
/**//*首先我们考虑怎样可以把动画应用到当前摄像机上。
          因为一个动画可以应用到一个节点上,所以可以创建
          一个节点并将当前摄像机attach到这个节点上去
*/

        SceneNode
* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
        camNode
->attachObject(mCamera);

        
//下面定义动画、动画轨迹以及关键帧:
        
// 定义动画,指定动画的名称及长度(这里为10秒)
        Animation* anim = mSceneMgr->createAnimation("CameraTrack"10);
        
// 指定动画关键帧之间的插值方式(包括线性插值和样条插值)
           anim->setInterpolationMode(Animation::IM_SPLINE);
        
// 定义动画的一个动画轨迹,并指定这个轨迹是作用到camNode节点上的
        NodeAnimationTrack* track = anim->createNodeTrack(0, camNode);
        
// 定义动画轨迹包含的关键帧,下面定义了四个关键帧,加上起始帧
        
// 五个关健帧形成了一个翻转的动画。
        TransformKeyFrame* key = track->createNodeKeyFrame(0); // startposition
        key = track->createNodeKeyFrame(2.5);
        key
->setTranslate(Vector3(500,500,-1000));
        key 
= track->createNodeKeyFrame(5);
        key
->setTranslate(Vector3(-1500,1000,-600));
        key 
= track->createNodeKeyFrame(7.5);
        key
->setTranslate(Vector3(0,-100,0));
        key 
= track->createNodeKeyFrame(10);
        key
->setTranslate(Vector3(0,0,0));        

        
//然后定义AnimationState类的对象,它和刚才定义的动画类相对应。设置动画的状态为启用:
        mAnimState = mSceneMgr->createAnimationState("CameraTrack");
        mAnimState
->setEnabled(true);    // 启用该动画
        
//到此,初始化工作就做完了。
    }

动画的初始化过程创建完成以后,我们就可以在我们想要的地方执行它了,作为一个例子,我们在virtual void createScene(void)的过程里面执行它就可以了。

我们必须在某个地方推动这些动画向前播放,这就涉及到了时间的问题。刚好,Ogre会自动地按照时间的推移而进行渲染工作,我们不需关心他们是如何渲染的,因为我们这里关心的是我们的动画怎么根据时间来进行播放,因此,我们可以在Ogre的项目向导中给我们定义了一个继承于ExampleFrameListener的类,我们可以在这个类的bool frameStarted(const FrameEvent& evt)过程中加入这句代码就可以了:mAnimState->addTime(evt.timeSinceLastFrame);

剩下的就只有运行我们的程序看看了。(注意,别把程序向导所帮我们写的代码注释了哦,否则我们什么也看不到的哦。)

如果我们想做一个平面呢,拷贝下面的代码吧:

    void CreatePlane()
    
...{
        Plane plane;
//定义一个水平面参数
        plane.normal = Vector3::UNIT_Y;//设置水平面的法线,垂直于Y轴
        plane.d = 100;                 //设置水平面的D参数:到原点的距离
        
//下面是根据刚才定义的水平面参数进行一个平面的创建
        MeshManager::getSingleton().createPlane("Myplane",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
            
1500,1500,20,20,true,1,60,60,Vector3::UNIT_Z);
        
//创建完平面,还要创建一个实体,有了实体才可以把场景放到节点当中去。
        Entity* pPlaneEnt = mSceneMgr->createEntity( "plane""Myplane" );
        pPlaneEnt
->setMaterialName("Examples/Rockwall");
        pPlaneEnt
->setCastShadows(false);
        
//把平面实例挂到场景管理器当中,从而实现其自动渲染出来。
        mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,99,0))->attachObject(pPlaneEnt);
    }

在什么时候执行这代码?你想什么时候执行都行的,但是你真想我说,我就只好告诉你,写在virtual void createScene(void)过程里吧,我也想不到该写到哪里去执行它了。执行的时候别晕了哦。执行来看看效果吧。这只是我学习过程中的一个小例子。谢谢捧场。

原创作品出自努力偷懒,转载请说明文章出处http://blog.csdn.net/kfarvid或 http://www.cnblogs.com/kfarvid/

posted @ 2007-08-03 22:17  努力偷懒  阅读(463)  评论(0编辑  收藏  举报