Commit 125e73ef authored by cutealien's avatar cutealien

Fix skinned meshes not playing their last frame.

Also clarified animation documentation to describe current behavior more exactly.
CSkinnedMesh had returned the last key instead of the number of keys.
Thx to whoever mentioned to me once that our example dwarf is not playing his full animation in the meshviewer.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5118 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 44e73315
--------------------------
Changes in 1.9 (not yet released)
- Fix skinned meshes not playing their last frame. Also clarified animation documentation to describe current behavior more exactly.
- Add IWriteFile::flush interface (thx @ JLouisB for the patch).
- CLightSceneNode::updateAbsolutePosition does now light recalculations. This is to fix using animators with lights.
- Fix collada export for objects with rotations around more than 1 axis.
......
......@@ -22,7 +22,8 @@ namespace scene
public:
//! Gets the frame count of the animated mesh.
/** \return The amount of frames. If the amount is 1,
/** Note that the play-time is usually getFrameCount()-1 as it stops as soon as the last frame-key is reached.
\return The amount of frames. If the amount is 1,
it is a static, non animated mesh. */
virtual u32 getFrameCount() const = 0;
......
......@@ -72,7 +72,11 @@ namespace scene
virtual void setCurrentFrame(f32 frame) = 0;
//! Sets the frame numbers between the animation is looped.
/** The default is 0 - MaximalFrameCount of the mesh.
/** The default is 0 to getFrameCount()-1 of the mesh.
Number of played frames is end-start.
It interpolates toward the last frame but stops when it is reached.
It does not interpolate back to start even when looping.
Looping animations should ensure last and first frame-key are identical.
\param begin: Start frame number of the loop.
\param end: End frame number of the loop.
\return True if successful, false if not. */
......
......@@ -850,7 +850,7 @@ void CAnimatedMeshSceneNode::setMesh(IAnimatedMesh* mesh)
// get start and begin time
setAnimationSpeed(Mesh->getAnimationSpeed()); // NOTE: This had been commented out (but not removed!) in r3526. Which caused meshloader-values for speed to be ignored unless users specified explicitly. Missing a test-case where this could go wrong so I put the code back in.
setFrameLoop(0, Mesh->getFrameCount());
setFrameLoop(0, Mesh->getFrameCount()-1);
}
......
......@@ -92,7 +92,7 @@ namespace scene
//! constructor
CSkinnedMesh::CSkinnedMesh()
: SkinningBuffers(0), AnimationFrames(0.f), FramesPerSecond(25.f),
: SkinningBuffers(0), EndFrame(0.f), FramesPerSecond(25.f),
LastAnimatedFrame(-1), SkinnedLastFrame(false),
InterpolationMode(EIM_LINEAR),
HasAnimation(false), PreparedForSkinning(false),
......@@ -124,7 +124,7 @@ CSkinnedMesh::~CSkinnedMesh()
//! If the amount is 1, it is a static (=non animated) mesh.
u32 CSkinnedMesh::getFrameCount() const
{
return core::floor32(AnimationFrames);
return core::floor32(EndFrame+1.f);
}
......@@ -878,22 +878,22 @@ void CSkinnedMesh::checkForAnimation()
if (HasAnimation)
{
//--- Find the length of the animation ---
AnimationFrames=0;
EndFrame=0;
for(i=0;i<AllJoints.size();++i)
{
if (AllJoints[i]->UseAnimationFrom)
{
if (AllJoints[i]->UseAnimationFrom->PositionKeys.size())
if (AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame > AnimationFrames)
AnimationFrames=AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame;
if (AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame > EndFrame)
EndFrame=AllJoints[i]->UseAnimationFrom->PositionKeys.getLast().frame;
if (AllJoints[i]->UseAnimationFrom->ScaleKeys.size())
if (AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame > AnimationFrames)
AnimationFrames=AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame;
if (AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame > EndFrame)
EndFrame=AllJoints[i]->UseAnimationFrom->ScaleKeys.getLast().frame;
if (AllJoints[i]->UseAnimationFrom->RotationKeys.size())
if (AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame > AnimationFrames)
AnimationFrames=AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame;
if (AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame > EndFrame)
EndFrame=AllJoints[i]->UseAnimationFrom->RotationKeys.getLast().frame;
}
}
}
......@@ -1053,11 +1053,11 @@ void CSkinnedMesh::finalize()
}
Key=&PositionKeys.getLast();
if (Key->frame!=AnimationFrames)
if (Key->frame!=EndFrame)
{
PositionKeys.push_back(*Key);
Key=&PositionKeys.getLast();
Key->frame=AnimationFrames;
Key->frame=EndFrame;
}
}
......@@ -1073,11 +1073,11 @@ void CSkinnedMesh::finalize()
}
Key=&ScaleKeys.getLast();
if (Key->frame!=AnimationFrames)
if (Key->frame!=EndFrame)
{
ScaleKeys.push_back(*Key);
Key=&ScaleKeys.getLast();
Key->frame=AnimationFrames;
Key->frame=EndFrame;
}
}
......@@ -1093,11 +1093,11 @@ void CSkinnedMesh::finalize()
}
Key=&RotationKeys.getLast();
if (Key->frame!=AnimationFrames)
if (Key->frame!=EndFrame)
{
RotationKeys.push_back(*Key);
Key=&RotationKeys.getLast();
Key->frame=AnimationFrames;
Key->frame=EndFrame;
}
}
}
......
......@@ -194,7 +194,7 @@ private:
core::aabbox3d<f32> BoundingBox;
f32 AnimationFrames;
f32 EndFrame;
f32 FramesPerSecond;
f32 LastAnimatedFrame;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment