作者: i_dovelemon
日期: 2014 / 12 / 17
来源: CSDN
主题: Custom Animator, Referenced count
引言
在昨天的文章《Irrlicht 3D Engine 笔记系列 之 教程4 - Movement》中,博主向大家保证会在今天向大家实际操作如何扩展Irrlicht引擎的Animator特性。如果读者对Irrlicht的Animator的特性不是很了解的话,请先了解下前面的那篇文章,本片文章是在上次文章的基础上进行的。
Custom Animator
经过昨天我们的分析,发现只要我们继承ISceneNodeAnimator这个接口来实现我们自己的Animator就可以了。所以下面,我们就按着这个思路来对创建我们自定义的Animator。
首先,对我们将要创建的Animator进行下简单的描述:
博主想要创建一个沿着某条直线进行循环运动,并且物体本身在旋转的Animator。博主称之为Roll Animator(翻滚动画)。
好了,在明确了我们想要创建的Animator的功能之后,我们就实际动手来创建一个。
首先,我们来申明一个CMyRollAnimator的类,这个类继承至ISceneNodeAnimator,并且复写其中的两个纯虚拟函数animateNode和createClone,申明头文件如下所示:
//-------------------------------------------------------------------------------------------------
// declaration : Copyright (c), by XJ , 2014. All right reserved .
// brief : This file will define the custom roll animator.
// author : XJ
// date : 2014 / 12 / 17
// version : 1.0
//--------------------------------------------------------------------------------------------------
#pragma once
#include<irrlicht.h>
using namespace irr ;
using namespace scene ;
using namespace core;
class CMyRollAnimator: public ISceneNodeAnimator
{
public:
CMyRollAnimator(vector3df _startPos, vector3df _endPos,
f32 _speed);
//animate a node
virtual void animateNode(ISceneNode* node, u32 timeMs);
//clone a animator
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0);
private:
vector3df m_vStartPos ;
vector3df m_vEndPos ;
vector3df m_vCurPos ;
f32 m_fSpeed ;
u32 m_uCurTime;
//internal usage
vector3df m_vDir ;
vector3df m_vRDir ;
};
读者可以看到博主上面定义的类非常的简单,只是添加了几个成员属性而已。除此之外就是复写的方法和一个构造函数。
为了实现前面描述的运动,我们来介绍下这里面成员的含义。首先,我们需要知道物体运动应该从哪里开始,到哪里结束,并且需要知道这个运动的速度以及当前运动的时间。另外两个成员属性用于内部计算使用。下面来看看这个类的明确实现是怎么样的:
#include"CMyRollAnimator.h"
//constructor
CMyRollAnimator::CMyRollAnimator(vector3df _startPos, vector3df _endPos,
f32 _speed)
:m_vStartPos(_startPos),
m_vEndPos(_endPos),
m_fSpeed(_speed),
m_vCurPos(_startPos),
m_uCurTime(0)
{
m_vDir = m_vEndPos - m_vStartPos ;
m_vDir.normalize();
m_vRDir = m_vDir ;
m_vRDir.rotateXZBy(90.0f);
}
//animate a node
void CMyRollAnimator::animateNode(ISceneNode* _pNode, u32 timeMs)
{
if(0 == m_uCurTime)
{
m_uCurTime = timeMs ;
_pNode->setPosition(m_vStartPos);
}
else
{
u32 _deltaTime = timeMs - m_uCurTime ;
f32 _fDeltaTime = _deltaTime / 1000.0f ;
m_uCurTime = timeMs ;
m_vCurPos += _fDeltaTime * m_fSpeed * m_vDir ;
if(abs(m_vCurPos.X - m_vEndPos.X) < 0.01f &&
abs(m_vCurPos.Y - m_vEndPos.Y) < 0.01f &&
abs(m_vCurPos.Z - m_vEndPos.Z) < 0.01f)
{
m_vCurPos = m_vStartPos ;
}
_pNode->setPosition(m_vCurPos);
_pNode->setRotation(-m_vRDir * 180.0f * timeMs/1000.0f);
}
}// end for animateNode
/