animation revisited with v.0.12.0

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
luckymutt
Posts: 453
Joined: Sun Mar 06, 2005 11:56 pm
Location: C-Ville

animation revisited with v.0.12.0

Post by luckymutt »

As mentioned in a pre-0.12.0 post, the problem I (and others) have had is with calling either an animation or rotation to trigger.
What seems to be happening is that during the entire run time, the animation position is being calculated, then when it is triggered, it begins displaying from the calculated position rather than from the begining frame, even when setCurrentFrame(1); is used.
Previoiusly, my code looked like this:

Code: Select all

if (node)
{
     if(distance > 200) 
         { 
               node->setAnimationSpeed(0);  
         }                             
                                   
      else if( distance < 200.0f) 
          { 
               node->setCurrentFrame(1);
               node->setFrameLoop(1,120);
               node->setAnimationSpeed(10); 
               node->setLoopMode(false); 
          }
}
reference:http://irrlicht.sourceforge.net/phpBB2/ ... php?t=8349
Niko suggested that the new ITimer class should address this.
Looking in the API, it says
The timer is reference counted, which means everything which calls stop() will also have to call start(), otherwise the timer may not start/stop corretly again.
However, so far as I try to use this, it seems to apply to the entire scene, not just the animation.

It only wants to be applied with "device->gettimer()->stop();" which is freezing the entire scene.

Anyone know how to implement the ITimer class to stop and start the time just for the animation?
Or any alternate way of actually getting the animation to start playing at the first frame?

This is really my last hurdle for putting my project together. Oddly enough, I ffigured this would be the easiest.
Reiyn
Posts: 23
Joined: Sat Mar 05, 2005 7:51 pm
Location: Canada

Post by Reiyn »

Bump,
This is a few months old now and still a bug that needs addressing =\
Reiyn
Creating "Chimera", an Online RPG
DAoC - Guinevere - Druid rr11
WoW - Gorgonnash - Druid 55
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I looked at it and was a little surprised...

Code: Select all

//! sets the current frame. from now on the animation is played from this frame.
void CAnimatedMeshSceneNode::setCurrentFrame(s32 frame)
{
}
No wonder calling setCurrentFrame isn't doing what you expect. I'm not sure why it isn't implemented, but it didn't seem hard to do.

Code: Select all

//! sets the current frame. from now on the animation is played from this frame.
void CAnimatedMeshSceneNode::setCurrentFrame(s32 frame)
{
   // if you pass an out of range value, we just clamp it
   if (frame < StartFrame)
      frame = StartFrame;
   else if (EndFrame < frame)
     frame = EndFrame;

   BeginFrameTime = 
      BeginFrameTime = os::Timer::getTime() - (s32)((frame - StartFrame) / (FramesPerSecond / 1000.f));
}
I also noticed another issue. If you have an animated mesh with 100 frames and you call setFrameLoop(0, 100), your request will be rejected. The second parameter must be less than the total number of frames. This is funny because the constructor sets the end frame to 100. Interestingly enough, you can pass a negative value as the start frame, which does cause problems. That fix is pretty simple.

Code: Select all

//! sets the frames between the animation is looped.
//! the default is 0 - MaximalFrameCount of the mesh.
bool CAnimatedMeshSceneNode::setFrameLoop(s32 begin, s32 end)
{
   if (!Mesh)
      return false;

   s32 frameCount = Mesh->getFrameCount();

   if (!(begin <= end && 0 <= begin && end <= frameCount))
      return false;

   StartFrame = begin;
   EndFrame = end;
   BeginFrameTime = os::Timer::getTime();

   return true;
}
Travis
Post Reply