Changed the frame calculation to diff-based, as suggested on the tracker.

Changed default frame rate from 250FPS to 25 to FPS.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2329 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2009-04-11 23:28:39 +00:00
parent 5c7c557dd5
commit 03cad465a3
2 changed files with 35 additions and 46 deletions

View File

@ -33,9 +33,9 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh,
const core::vector3df& scale) const core::vector3df& scale)
: IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0), : IAnimatedMeshSceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
BeginFrameTime(0), StartFrame(0), EndFrame(0), FramesPerSecond(0.f), BeginFrameTime(0), StartFrame(0), EndFrame(0), FramesPerSecond(0.f),
CurrentFrameNr(0.f), CurrentFrameNr(0.f), LastTimeMs(0),
JointMode(EJUOR_NONE), JointsUsed(false),
TransitionTime(0), Transiting(0.f), TransitingBlend(0.f), TransitionTime(0), Transiting(0.f), TransitingBlend(0.f),
JointMode(EJUOR_NONE), JointsUsed(false),
Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(0), Looping(true), ReadOnlyMaterials(false), RenderFromIdentity(0),
LoopCallBack(0), PassCount(0), Shadow(0), LoopCallBack(0), PassCount(0), Shadow(0),
MD3Special ( 0 ) MD3Special ( 0 )
@ -45,7 +45,7 @@ CAnimatedMeshSceneNode::CAnimatedMeshSceneNode(IAnimatedMesh* mesh,
#endif #endif
BeginFrameTime = os::Timer::getTime(); BeginFrameTime = os::Timer::getTime();
FramesPerSecond = 25.f/100.f; FramesPerSecond = 25.f/1000.f;
setMesh(mesh); setMesh(mesh);
} }
@ -95,11 +95,11 @@ f32 CAnimatedMeshSceneNode::getFrameNr() const
} }
f32 CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs) void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
{ {
if (Transiting!=0.f) if (Transiting!=0.f)
{ {
TransitingBlend = (f32)(timeMs-BeginFrameTime) * Transiting; TransitingBlend += (f32)(timeMs) * Transiting;
if (TransitingBlend > 1.f) if (TransitingBlend > 1.f)
{ {
Transiting=0.f; Transiting=0.f;
@ -107,65 +107,52 @@ f32 CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
} }
} }
if (StartFrame==EndFrame) if ((StartFrame==EndFrame) || (FramesPerSecond==0.f))
return (f32)StartFrame; //Support for non animated meshes {
if (FramesPerSecond==0.f) CurrentFrameNr = (f32)StartFrame; //Support for non animated meshes
return (f32)StartFrame; }
else if (Looping)
if (Looping)
{ {
// play animation looped // play animation looped
CurrentFrameNr += timeMs * FramesPerSecond;
const s32 lenInMs = abs(s32( (EndFrame - StartFrame) / FramesPerSecond));
if (FramesPerSecond > 0.f) //forwards... if (FramesPerSecond > 0.f) //forwards...
{ {
return StartFrame + ( (timeMs - BeginFrameTime) % lenInMs) * FramesPerSecond; if (CurrentFrameNr > EndFrame)
CurrentFrameNr -= (EndFrame-StartFrame);
} }
else //backwards... else //backwards...
{ {
return EndFrame - ( (timeMs - BeginFrameTime) % lenInMs)* -FramesPerSecond; if (CurrentFrameNr < StartFrame)
CurrentFrameNr += (EndFrame-StartFrame);
} }
} }
else else
{ {
// play animation non looped // play animation non looped
f32 frame; CurrentFrameNr += timeMs * FramesPerSecond;
if (FramesPerSecond > 0.f) //forwards... if (FramesPerSecond > 0.f) //forwards...
{ {
const f32 deltaFrame = ( timeMs - BeginFrameTime ) * FramesPerSecond; if (CurrentFrameNr > (f32)EndFrame)
frame = StartFrame + deltaFrame;
if (frame > (f32)EndFrame)
{ {
frame = (f32)EndFrame; CurrentFrameNr = (f32)EndFrame;
if (LoopCallBack) if (LoopCallBack)
LoopCallBack->OnAnimationEnd(this); LoopCallBack->OnAnimationEnd(this);
} }
} }
else //backwards... (untested) else //backwards...
{ {
const f32 deltaFrame = ( timeMs - BeginFrameTime ) * -FramesPerSecond; if (CurrentFrameNr < (f32)StartFrame)
frame = EndFrame - deltaFrame;
if (frame < (f32)StartFrame)
{ {
frame = (f32)StartFrame; CurrentFrameNr = (f32)StartFrame;
if (LoopCallBack) if (LoopCallBack)
LoopCallBack->OnAnimationEnd(this); LoopCallBack->OnAnimationEnd(this);
} }
} }
return frame;
} }
} }
//! frame
void CAnimatedMeshSceneNode::OnRegisterSceneNode() void CAnimatedMeshSceneNode::OnRegisterSceneNode()
{ {
if (IsVisible) if (IsVisible)
@ -255,7 +242,7 @@ IMesh * CAnimatedMeshSceneNode::getMeshForCurrentFrame(bool forceRecalcOfControl
//! OnAnimate() is called just before rendering the whole scene. //! OnAnimate() is called just before rendering the whole scene.
void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs) void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
{ {
CurrentFrameNr = buildFrameNr ( timeMs ); buildFrameNr(timeMs-LastTimeMs);
if ( Mesh ) if ( Mesh )
{ {
@ -264,6 +251,7 @@ void CAnimatedMeshSceneNode::OnAnimate(u32 timeMs)
if ( mesh ) if ( mesh )
Box = mesh->getBoundingBox(); Box = mesh->getBoundingBox();
} }
LastTimeMs = timeMs;
IAnimatedMeshSceneNode::OnAnimate ( timeMs ); IAnimatedMeshSceneNode::OnAnimate ( timeMs );
} }
@ -540,9 +528,9 @@ bool CAnimatedMeshSceneNode::setFrameLoop(s32 begin, s32 end)
EndFrame = core::s32_clamp(end, StartFrame, maxFrameCount); EndFrame = core::s32_clamp(end, StartFrame, maxFrameCount);
} }
if (FramesPerSecond < 0) if (FramesPerSecond < 0)
setCurrentFrame ( (f32)EndFrame ); setCurrentFrame((f32)EndFrame);
else else
setCurrentFrame ( (f32)StartFrame ); setCurrentFrame((f32)StartFrame);
return true; return true;
} }
@ -916,6 +904,7 @@ void CAnimatedMeshSceneNode::updateAbsolutePosition()
} }
} }
//! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set) //! Set the joint update mode (0-unused, 1-get joints only, 2-set joints only, 3-move and set)
void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode) void CAnimatedMeshSceneNode::setJointMode(E_JOINT_UPDATE_ON_RENDER mode)
{ {
@ -940,6 +929,7 @@ void CAnimatedMeshSceneNode::setTransitionTime(f32 time)
} }
} }
//! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected) //! render mesh ignoring its transformation. Used with ragdolls. (culling is unaffected)
void CAnimatedMeshSceneNode::setRenderFromIdentity( bool On ) void CAnimatedMeshSceneNode::setRenderFromIdentity( bool On )
{ {
@ -947,7 +937,6 @@ void CAnimatedMeshSceneNode::setRenderFromIdentity( bool On )
} }
//! updates the joint positions of this mesh //! updates the joint positions of this mesh
void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions) void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
{ {
@ -1015,8 +1004,6 @@ void CAnimatedMeshSceneNode::animateJoints(bool CalculateAbsolutePositions)
} }
} }
if (CalculateAbsolutePositions) if (CalculateAbsolutePositions)
{ {
//---slow--- //---slow---
@ -1052,6 +1039,7 @@ void CAnimatedMeshSceneNode::checkJoints()
} }
} }
/*! /*!
*/ */
void CAnimatedMeshSceneNode::beginTransition() void CAnimatedMeshSceneNode::beginTransition()
@ -1078,6 +1066,7 @@ void CAnimatedMeshSceneNode::beginTransition()
TransitingBlend = 0.f; TransitingBlend = 0.f;
} }
/*! /*!
*/ */
ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
@ -1119,7 +1108,6 @@ ISceneNode* CAnimatedMeshSceneNode::clone(ISceneNode* newParent, ISceneManager*
} }
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr

View File

@ -164,7 +164,7 @@ namespace scene
//! Get a static mesh for the current frame of this animated mesh //! Get a static mesh for the current frame of this animated mesh
IMesh* getMeshForCurrentFrame(bool forceRecalcOfControlJoints); IMesh* getMeshForCurrentFrame(bool forceRecalcOfControlJoints);
f32 buildFrameNr( u32 timeMs); void buildFrameNr(u32 timeMs);
void checkJoints(); void checkJoints();
void beginTransition(); void beginTransition();
@ -178,14 +178,15 @@ namespace scene
f32 FramesPerSecond; f32 FramesPerSecond;
f32 CurrentFrameNr; f32 CurrentFrameNr;
//0-unused, 1-get joints only, 2-set joints only, 3-move and set u32 LastTimeMs;
E_JOINT_UPDATE_ON_RENDER JointMode;
bool JointsUsed;
u32 TransitionTime; //Transition time in millisecs u32 TransitionTime; //Transition time in millisecs
f32 Transiting; //is mesh transiting (plus cache of TransitionTime) f32 Transiting; //is mesh transiting (plus cache of TransitionTime)
f32 TransitingBlend; //0-1, calculated on buildFrameNr f32 TransitingBlend; //0-1, calculated on buildFrameNr
//0-unused, 1-get joints only, 2-set joints only, 3-move and set
E_JOINT_UPDATE_ON_RENDER JointMode;
bool JointsUsed;
bool Looping; bool Looping;
bool ReadOnlyMaterials; bool ReadOnlyMaterials;
bool RenderFromIdentity; bool RenderFromIdentity;