PDA

View Full Version : Simple Animation Question


KiroNeem
2004.10.27, 03:04 PM
I've finally got my threads working correctly and now I am on to animation for my game. Basically for every animation I have a Animation Struct.

typedef struct
{
int numberOfFrames;
int frameLength;

int currentFrame;
int intoFrame;
} Animation;

typedef struct
{
GLuint * texID;
int width;
int height;
Animation animation;
} Sprite;

Then from here I go to declare a sprite, then in each loop I handle which frame the animation is at with this.

Animation handleAnimation( Animation animation, int timeElapsed )
{
animation.intoFrame += timeElapsed;
while( animation.intoFrame > animation.frameLength)
{
animation.currentFrame++;
if(animation.currentFrame >= animation.numberOfFrames)
animation.currentFrame = 0;

animation.intoFrame -= animation.frameLength;
}

return animation;
}

In all essence it works perfectly, I'm just wondering if there is a better way to do this? better as in faster.

Joseph Duchesne
2004.10.27, 09:28 PM
Well, you could use one texture and use seperate portions of it. For example if you did it vertically and had 2 frames you would access the first at (0,0) (0,.5) (1,.5) (1,0) for left-top, left-bottom, right-bottom, top-bottom

LongJumper
2004.10.27, 09:36 PM
void handleAnimation(Animation* animation, float timeElapsed)
{
animation->intoFrame += timeElapsed;
if( animation->intoFrame > animation->frameLength)
{
animation->currentFrame++;
if(animation->currentFrame >= animation->numberOfFrames)
animation->currentFrame = 0;
animation->intoFrame = 0;
}
}

PowerMacX
2004.10.31, 07:01 PM
Instead of:
animation.currentFrame++;
if(animation.currentFrame >= animation.numberOfFrames)
animation.currentFrame = 0;

you could just use:
animation.currentFrame = (animation.currentFrame+1) % animation.numberOfFrames;

EDIT: also, there is no need to use a while loop to find out which frame to draw, just do something like:
void handleAnimation( Animation& animation, int timeElapsed )
{
animation.intoFrame += timeElapsed;
int framesElapsed = animation.intoFrame/animation.frameLength;
animation.currentFrame = (animation.currentFrame+framesElapsed) % animation.numberOfFrames;
animation.intoFrame -= framesElapsed*animation.frameLength;
}

James
2004.11.20, 03:45 AM
animation.currentFrame = (animation.currentFrame+1) % animation.numberOfFrames;


Wouldnt the branch execute quicker than the divide? Thou we are talking millionths of a second.

skyhawk
2004.11.20, 04:20 AM
animation.currentFrame = (animation.currentFrame+1) % animation.numberOfFrames;


Wouldnt the branch execute quicker than the divide? Thou we are talking millionths of a second.
modulo is faster than branching, in fact, branching is one of the worse things you can do in programming

James
2004.11.20, 04:25 AM
But the branch difference is only 5-10 instructions apart so 99% of the time all the code would be in the processor so no memory fetch would result (where there's substantial slowdown)

However I am not up with the current G3/G4/G5 architectures. I am talking from 68K/603/604 experience.

skyhawk
2004.11.20, 05:10 AM
while it is only 5-10 instructions apart, there is still the possibility of wrongly predicting the branch, thus causing you to have to flush your pipes. The G5 has a much longer pipe now. while it is only minor details, branching is much slowing than computation, most of the time

James
2004.11.20, 05:53 AM
From the MPC7450 (PowerPC G4) User Manual it states most integer instructions are only 1 cycle and a bad branch prediction has a penalty of 7 cycles. I will also assume jumps are only 1 cycle.

animation.currentFrame++;
if(animation.currentFrame >= animation.numberOfFrames)
animation.currentFrame = 0;

This would incur 3 cycles on a good branch prediction or 10 cycles on a bad prediction.


animation.currentFrame = (animation.currentFrame+1) % animation.numberOfFrames;

This would incur 2 cycles making you right skyhawk. Of course this is the case if everything was in L1 cache and loaded into registers beforehand. If it wasn't, then you would see the cycle counts skyrocket but the skyhawk's example would still win.

Sorry to doubt you skyhawk, however for any other doubters, there's the proof.

DoG
2004.11.20, 07:06 AM
This is the kind of optimisation without any point. The time spent in that is miniscule compared to the time spent in rendering the aforementioned animation, no matter how simple that rendering is.

James
2004.11.20, 07:40 AM
That is true, but now that I know beforehand of this, any future games would use the new code. However I would think that compilers are also smart enough to include this code automatically.

DoG
2004.11.20, 12:17 PM
This is the kind of change no compiler can make to date, because it would have to perform some quite complex semantical analysis of the code to understand what you want to do.