- ISceneNodeAnimators can now be disabled and paused.

- Moved StartTime in the ISceneNodeAnimators class instead of derived classes.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4767 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2014-04-08 14:39:11 +00:00
parent c11d706e6a
commit 7d8307b1da
18 changed files with 153 additions and 98 deletions

View File

@ -1,6 +1,7 @@
--------------------------
Changes in 1.9 (not yet released)
- ISceneNodeAnimators can now be disabled and paused.
- Maya camera no longer get's stuck in "rotating" state when a mouse-up event is lost (thx @ JLouisB for reporting).
- Focus behavior of IGUIEnvironment now controllable (right-click focus, mouse-over focus). Disabled elements no longer get the focus unless users enforce it.
- Buttons can now now have 7 more image-states, 1 more sprite-state and the sprites are now scaleable.

View File

@ -119,7 +119,10 @@ namespace scene
// node without the iterator becoming invalid
ISceneNodeAnimator* anim = *ait;
++ait;
anim->animateNode(this, timeMs);
if ( anim->isEnabled() )
{
anim->animateNode(this, timeMs);
}
}
// update absolute position
@ -539,7 +542,7 @@ namespace scene
}
//! Set a culling style or disable culling completely.
//! Set a culling style or disable culling completely.
/** Box cullling (EAC_BOX) is set by default. Note that not
all SceneNodes support culling and that some nodes always cull
their geometry because it is their only reason for existence,

View File

@ -9,6 +9,7 @@
#include "vector3d.h"
#include "ESceneNodeAnimatorTypes.h"
#include "IAttributeExchangingObject.h"
#include "IAttributes.h"
#include "IEventReceiver.h"
namespace irr
@ -30,6 +31,10 @@ namespace scene
class ISceneNodeAnimator : public io::IAttributeExchangingObject, public IEventReceiver
{
public:
ISceneNodeAnimator() : IsEnabled(true), PauseTimeSum(0), PauseTimeStart(0), StartTime(0)
{
}
//! Animates a scene node.
/** \param node Node to animate.
\param timeMs Current time in milli seconds. */
@ -68,24 +73,93 @@ namespace scene
{
return false;
}
//! Reset a time-based movement by changing the starttime.
/** By default most animators start on object creation.
Commonly you will use irr::ITimer::getTime().
This value is ignored by animators which don't work with a starttime.
CSceneNodeAnimatorRotation currently overwrites this value constantly (might be changed in the future).
This value is ignored by animators which don't work with a starttime.
Known problems: CSceneNodeAnimatorRotation currently overwrites this value constantly (might be changed in the future).
\param time Commonly you will use irr::ITimer::getTime().
\param resetPauseTime Reset internal pause time for enabling/diabling animators as well
*/
virtual void setStartTime(u32 time)
virtual void setStartTime(u32 time, bool resetPauseTime=true)
{
StartTime = time;
if ( resetPauseTime )
{
PauseTimeStart = 0;
PauseTimeSum = 0;
}
}
//! Get the starttime.
/** This will return 0 for by animators which don't work with a starttime. */
//! Get the starttime.
/** This will return 0 for by animators which don't work with a starttime unless a starttime was manually set */
virtual irr::u32 getStartTime() const
{
return 0;
return StartTime;
}
//! Sets the enabled state of this element.
/**
\param enabled When set to false ISceneNodes will not update the animator anymore.
Animators themself usually don't care. So manual calls to animateNode still work.
\param timeNow When set to values > 0 on enabling and disabling an internal timer will be increased by the time disabled time.
Animator decide themself how to handle that timer, but generally setting it will allow you to pause an animator, so it
will continue at the same position when you enable it again. To use that pass irr::ITimer::getTime() as value.
Animators with no timers will just ignore this.
*/
virtual void setEnabled(bool enabled, u32 timeNow=0)
{
if ( enabled == IsEnabled )
return;
IsEnabled = enabled;
if ( enabled )
{
if ( timeNow > 0 && PauseTimeStart > 0 )
PauseTimeSum += timeNow-PauseTimeStart;
}
else
{
PauseTimeStart = timeNow;
}
}
virtual bool isEnabled() const
{
return IsEnabled;
}
//! Writes attributes of the scene node animator.
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const _IRR_OVERRIDE_
{
out->addBool("IsEnabled", IsEnabled);
// timers not serialized as they usually depend on system-time which is different on each application start.
}
//! Reads attributes of the scene node animator.
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_
{
IsEnabled = in->getAttributeAsBool("IsEnabled", IsEnabled);
PauseTimeSum = 0;
PauseTimeStart = 0;
}
protected:
/** This method can be used by clone() implementations of
derived classes
\param toCopyFrom The animator from which the values are copied */
void cloneMembers(const ISceneNodeAnimator* toCopyFrom)
{
IsEnabled = toCopyFrom->IsEnabled;
PauseTimeSum = toCopyFrom->IsEnabled;
PauseTimeStart = toCopyFrom->PauseTimeStart;
StartTime = toCopyFrom->StartTime;
}
bool IsEnabled; //! Only enabled animators are updated
u32 PauseTimeSum; //! Sum up time which the animator was disabled
u32 PauseTimeStart; //! Last time setEnabled(false) was called with a timer > 0
u32 StartTime; //! Used by animators which are time-based, ignored otherwise.
};

View File

@ -427,7 +427,7 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time)
if (newParticles && array)
{
s32 j=Particles.size();
if (newParticles > 16250-j)
if (newParticles > 16250-j) // avoid having more than 64k vertices in the scenenode
newParticles=16250-j;
Particles.set_used(j+newParticles);
for (s32 i=j; i<j+newParticles; ++i)

View File

@ -345,6 +345,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorCameraFPS::createClone(ISceneNode* node, I
CSceneNodeAnimatorCameraFPS * newAnimator =
new CSceneNodeAnimatorCameraFPS(CursorControl, RotateSpeed, MoveSpeed, JumpSpeed,
0, 0, NoVerticalMovement);
newAnimator->cloneMembers(this);
newAnimator->setKeyMap(KeyMap);
return newAnimator;
}

View File

@ -314,6 +314,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorCameraMaya::createClone(ISceneNode* node,
{
CSceneNodeAnimatorCameraMaya * newAnimator =
new CSceneNodeAnimatorCameraMaya(CursorControl, RotateSpeed, ZoomSpeed, TranslateSpeed);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -243,6 +243,8 @@ void CSceneNodeAnimatorCollisionResponse::setNode(ISceneNode* node)
//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorCollisionResponse::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNodeAnimatorCollisionResponse::serializeAttributes(out, options);
out->addVector3d("Radius", Radius);
out->addVector3d("Gravity", Gravity);
out->addVector3d("Translation", Translation);
@ -253,10 +255,12 @@ void CSceneNodeAnimatorCollisionResponse::serializeAttributes(io::IAttributes* o
//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorCollisionResponse::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
Radius = in->getAttributeAsVector3d("Radius");
Gravity = in->getAttributeAsVector3d("Gravity");
Translation = in->getAttributeAsVector3d("Translation");
AnimateCameraTarget = in->getAttributeAsBool("AnimateCameraTarget");
ISceneNodeAnimatorCollisionResponse::deserializeAttributes(in, options);
Radius = in->getAttributeAsVector3d("Radius", Radius);
Gravity = in->getAttributeAsVector3d("Gravity", Gravity);
Translation = in->getAttributeAsVector3d("Translation", Translation);
AnimateCameraTarget = in->getAttributeAsBool("AnimateCameraTarget", AnimateCameraTarget);
}
@ -267,7 +271,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorCollisionResponse::createClone(ISceneNode*
CSceneNodeAnimatorCollisionResponse * newAnimator =
new CSceneNodeAnimatorCollisionResponse(newManager, World, Object, Radius,
(Gravity * 1000.0f), Translation, SlidingSpeed);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -24,7 +24,7 @@ CSceneNodeAnimatorDelete::CSceneNodeAnimatorDelete(ISceneManager* manager, u32 t
//! animates a scene node
void CSceneNodeAnimatorDelete::animateNode(ISceneNode* node, u32 timeMs)
{
if (timeMs > FinishTime)
if (timeMs > FinishTime+PauseTimeSum)
{
HasFinished = true;
if(node && SceneManager)
@ -44,6 +44,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorDelete::createClone(ISceneNode* node, ISce
CSceneNodeAnimatorDelete* newAnimator =
new CSceneNodeAnimatorDelete(newManager, FinishTime);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -15,11 +15,14 @@ CSceneNodeAnimatorFlyCircle::CSceneNodeAnimatorFlyCircle(u32 time,
const core::vector3df& center, f32 radius, f32 speed,
const core::vector3df& direction, f32 radiusEllipsoid)
: Center(center), Direction(direction), Radius(radius),
RadiusEllipsoid(radiusEllipsoid), Speed(speed), StartTime(time)
RadiusEllipsoid(radiusEllipsoid), Speed(speed)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFlyCircle");
#endif
StartTime = time;
init();
}
@ -45,10 +48,10 @@ void CSceneNodeAnimatorFlyCircle::animateNode(ISceneNode* node, u32 timeMs)
f32 time;
// Check for the condition where the StartTime is in the future.
if(StartTime > timeMs)
time = ((s32)timeMs - (s32)StartTime) * Speed;
if(StartTime+PauseTimeSum > timeMs)
time = ((s32)timeMs - (s32)(StartTime+PauseTimeSum)) * Speed;
else
time = (timeMs-StartTime) * Speed;
time = (timeMs-(StartTime+PauseTimeSum)) * Speed;
// node->setPosition(Center + Radius * ((VecU*cosf(time)) + (VecV*sinf(time))));
f32 r2 = RadiusEllipsoid == 0.f ? Radius : RadiusEllipsoid;
@ -59,6 +62,8 @@ void CSceneNodeAnimatorFlyCircle::animateNode(ISceneNode* node, u32 timeMs)
//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorFlyCircle::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNodeAnimator::serializeAttributes(out, options);
out->addVector3d("Center", Center);
out->addFloat("Radius", Radius);
out->addFloat("Speed", Speed);
@ -70,6 +75,8 @@ void CSceneNodeAnimatorFlyCircle::serializeAttributes(io::IAttributes* out, io::
//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorFlyCircle::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNodeAnimator::deserializeAttributes(in, options);
Center = in->getAttributeAsVector3d("Center");
Radius = in->getAttributeAsFloat("Radius");
Speed = in->getAttributeAsFloat("Speed");
@ -89,6 +96,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorFlyCircle::createClone(ISceneNode* node, I
{
CSceneNodeAnimatorFlyCircle * newAnimator =
new CSceneNodeAnimatorFlyCircle(StartTime, Center, Radius, Speed, Direction, RadiusEllipsoid);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -38,18 +38,6 @@ namespace scene
(IReferenceCounted::drop()) the returned pointer after calling
this. */
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) _IRR_OVERRIDE_;
//! Reset a time-based movement by changing the starttime.
virtual void setStartTime(u32 time) _IRR_OVERRIDE_
{
StartTime = time;
}
//! Get the starttime.
virtual irr::u32 getStartTime() const _IRR_OVERRIDE_
{
return StartTime;
}
private:
// do some initial calculations
@ -65,7 +53,6 @@ namespace scene
f32 Radius;
f32 RadiusEllipsoid;
f32 Speed;
u32 StartTime;
};

View File

@ -15,13 +15,15 @@ CSceneNodeAnimatorFlyStraight::CSceneNodeAnimatorFlyStraight(const core::vector3
const core::vector3df& endPoint, u32 timeForWay,
bool loop, u32 now, bool pingpong)
: ISceneNodeAnimatorFinishing(now + timeForWay),
Start(startPoint), End(endPoint), TimeFactor(0.0f), StartTime(now),
Start(startPoint), End(endPoint), TimeFactor(0.0f),
TimeForWay(timeForWay), Loop(loop), PingPong(pingpong)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFlyStraight");
#endif
StartTime = now;
recalculateIntermediateValues();
}
@ -40,7 +42,7 @@ void CSceneNodeAnimatorFlyStraight::animateNode(ISceneNode* node, u32 timeMs)
if (!node)
return;
u32 t = (timeMs-StartTime);
u32 t = (timeMs-(StartTime+PauseTimeSum));
core::vector3df pos;
@ -77,6 +79,8 @@ void CSceneNodeAnimatorFlyStraight::animateNode(ISceneNode* node, u32 timeMs)
//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorFlyStraight::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNodeAnimatorFinishing::serializeAttributes(out, options);
out->addVector3d("Start", Start);
out->addVector3d("End", End);
out->addInt("TimeForWay", TimeForWay);
@ -88,6 +92,8 @@ void CSceneNodeAnimatorFlyStraight::serializeAttributes(io::IAttributes* out, io
//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorFlyStraight::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNodeAnimatorFinishing::deserializeAttributes(in, options);
Start = in->getAttributeAsVector3d("Start");
End = in->getAttributeAsVector3d("End");
TimeForWay = in->getAttributeAsInt("TimeForWay");
@ -102,6 +108,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorFlyStraight::createClone(ISceneNode* node,
{
CSceneNodeAnimatorFlyStraight * newAnimator =
new CSceneNodeAnimatorFlyStraight(Start, End, TimeForWay, Loop, StartTime, PingPong);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -37,19 +37,6 @@ namespace scene
/** Please note that you will have to drop
(IReferenceCounted::drop()) the returned pointer after calling this. */
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) _IRR_OVERRIDE_;
//! Reset a time-based movement by changing the starttime.
virtual void setStartTime(u32 time) _IRR_OVERRIDE_
{
StartTime = time;
}
//! Get the starttime.
virtual irr::u32 getStartTime() const _IRR_OVERRIDE_
{
return StartTime;
}
private:
@ -59,7 +46,6 @@ namespace scene
core::vector3df End;
core::vector3df Vector;
f32 TimeFactor;
u32 StartTime;
u32 TimeForWay;
bool Loop;
bool PingPong;

View File

@ -14,12 +14,14 @@ namespace scene
CSceneNodeAnimatorFollowSpline::CSceneNodeAnimatorFollowSpline(u32 time,
const core::array<core::vector3df>& points, f32 speed,
f32 tightness, bool loop, bool pingpong)
: ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness), StartTime(time)
: ISceneNodeAnimatorFinishing(0), Points(points), Speed(speed), Tightness(tightness)
, Loop(loop), PingPong(pingpong)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorFollowSpline");
#endif
StartTime = time;
}
@ -44,7 +46,7 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs)
}
if (pSize==1)
{
if ( timeMs > StartTime )
if ( timeMs > (StartTime+PauseTimeSum) )
{
node->setPosition(Points[0]);
if ( !Loop )
@ -53,7 +55,7 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs)
return;
}
const f32 dt = ( (timeMs-StartTime) * Speed * 0.001f );
const f32 dt = ( (timeMs-(StartTime+PauseTimeSum)) * Speed * 0.001f );
const s32 unwrappedIdx = core::floor32( dt );
if ( !Loop && unwrappedIdx >= (s32)pSize-1 )
{
@ -91,6 +93,8 @@ void CSceneNodeAnimatorFollowSpline::animateNode(ISceneNode* node, u32 timeMs)
//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNodeAnimatorFinishing::serializeAttributes(out, options);
out->addFloat("Speed", Speed);
out->addFloat("Tightness", Tightness);
out->addBool("Loop", Loop);
@ -118,6 +122,8 @@ void CSceneNodeAnimatorFollowSpline::serializeAttributes(io::IAttributes* out, i
//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorFollowSpline::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNodeAnimatorFinishing::deserializeAttributes(in, options);
Speed = in->getAttributeAsFloat("Speed");
Tightness = in->getAttributeAsFloat("Tightness");
Loop = in->getAttributeAsBool("Loop");
@ -151,6 +157,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorFollowSpline::createClone(ISceneNode* node
{
CSceneNodeAnimatorFollowSpline * newAnimator =
new CSceneNodeAnimatorFollowSpline(StartTime, Points, Speed, Tightness);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -41,18 +41,6 @@ namespace scene
(IReferenceCounted::drop()) the returned pointer after calling
this. */
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) _IRR_OVERRIDE_;
//! Reset a time-based movement by changing the starttime.
virtual void setStartTime(u32 time) _IRR_OVERRIDE_
{
StartTime = time;
}
//! Get the starttime.
virtual irr::u32 getStartTime() const _IRR_OVERRIDE_
{
return StartTime;
}
protected:
@ -62,7 +50,6 @@ namespace scene
core::array< core::vector3df > Points;
f32 Speed;
f32 Tightness;
u32 StartTime;
bool Loop;
bool PingPong;
};

View File

@ -12,11 +12,13 @@ namespace scene
//! constructor
CSceneNodeAnimatorRotation::CSceneNodeAnimatorRotation(u32 time, const core::vector3df& rotation)
: Rotation(rotation), StartTime(time)
: Rotation(rotation)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorRotation");
#endif
StartTime = time;
}
@ -48,6 +50,8 @@ void CSceneNodeAnimatorRotation::animateNode(ISceneNode* node, u32 timeMs)
//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorRotation::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNodeAnimator::serializeAttributes(out, options);
out->addVector3d("Rotation", Rotation);
}
@ -55,6 +59,8 @@ void CSceneNodeAnimatorRotation::serializeAttributes(io::IAttributes* out, io::S
//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorRotation::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNodeAnimator::deserializeAttributes(in, options);
Rotation = in->getAttributeAsVector3d("Rotation");
}
@ -63,6 +69,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorRotation::createClone(ISceneNode* node, IS
{
CSceneNodeAnimatorRotation * newAnimator =
new CSceneNodeAnimatorRotation(StartTime, Rotation);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -34,23 +34,10 @@ namespace scene
/** Please note that you will have to drop
(IReferenceCounted::drop()) the returned pointer after calling this. */
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) _IRR_OVERRIDE_;
//! Reset a time-based movement by changing the starttime.
virtual void setStartTime(u32 time) _IRR_OVERRIDE_
{
StartTime = time;
}
//! Get the starttime.
virtual irr::u32 getStartTime() const _IRR_OVERRIDE_
{
return StartTime;
}
private:
core::vector3df Rotation;
u32 StartTime;
};

View File

@ -15,7 +15,7 @@ namespace scene
CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array<video::ITexture*>& textures,
s32 timePerFrame, bool loop, u32 now)
: ISceneNodeAnimatorFinishing(0),
TimePerFrame(timePerFrame), StartTime(now), Loop(loop)
TimePerFrame(timePerFrame), Loop(loop)
{
#ifdef _DEBUG
setDebugName("CSceneNodeAnimatorTexture");
@ -29,6 +29,7 @@ CSceneNodeAnimatorTexture::CSceneNodeAnimatorTexture(const core::array<video::IT
Textures.push_back(textures[i]);
}
StartTime = now;
FinishTime = now + (timePerFrame * Textures.size());
}
@ -56,10 +57,10 @@ void CSceneNodeAnimatorTexture::animateNode(ISceneNode* node, u32 timeMs)
if (Textures.size())
{
const u32 t = (timeMs-StartTime);
const u32 t = (timeMs-(StartTime+PauseTimeSum));
u32 idx = 0;
if (!Loop && timeMs >= FinishTime)
if (!Loop && timeMs >= FinishTime+PauseTimeSum)
{
idx = Textures.size() - 1;
HasFinished = true;
@ -78,6 +79,8 @@ void CSceneNodeAnimatorTexture::animateNode(ISceneNode* node, u32 timeMs)
//! Writes attributes of the scene node animator.
void CSceneNodeAnimatorTexture::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
{
ISceneNodeAnimatorFinishing::serializeAttributes(out, options);
out->addInt("TimePerFrame", TimePerFrame);
out->addBool("Loop", Loop);
@ -101,6 +104,8 @@ void CSceneNodeAnimatorTexture::serializeAttributes(io::IAttributes* out, io::SA
//! Reads attributes of the scene node animator.
void CSceneNodeAnimatorTexture::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
{
ISceneNodeAnimatorFinishing::deserializeAttributes(in, options);
TimePerFrame = in->getAttributeAsInt("TimePerFrame");
Loop = in->getAttributeAsBool("Loop");
@ -130,6 +135,7 @@ ISceneNodeAnimator* CSceneNodeAnimatorTexture::createClone(ISceneNode* node, ISc
{
CSceneNodeAnimatorTexture * newAnimator =
new CSceneNodeAnimatorTexture(Textures, TimePerFrame, Loop, StartTime);
newAnimator->cloneMembers(this);
return newAnimator;
}

View File

@ -41,25 +41,13 @@ namespace scene
this. */
virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0) _IRR_OVERRIDE_;
//! Reset a time-based movement by changing the starttime.
virtual void setStartTime(u32 time) _IRR_OVERRIDE_
{
StartTime = time;
}
//! Get the starttime.
virtual irr::u32 getStartTime() const _IRR_OVERRIDE_
{
return StartTime;
}
private:
void clearTextures();
core::array<video::ITexture*> Textures;
u32 TimePerFrame;
u32 StartTime;
bool Loop;
};