Simple Animation Question

KiroNeem
Unregistered
 
Post: #1
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.
Quote this message in a reply
Nibbie
Posts: 1
Joined: 2010.11
Post: #2
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
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #3
Code:
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;
    }
}
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #4
Instead of:
Code:
animation.currentFrame++;
if(animation.currentFrame >= animation.numberOfFrames)
    animation.currentFrame = 0;

you could just use:
Code:
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:
Code:
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;
}
Quote this message in a reply
James
Unregistered
 
Post: #5
Code:
animation.currentFrame = (animation.currentFrame+1) % animation.numberOfFrames;


Wouldnt the branch execute quicker than the divide? Thou we are talking millionths of a second.
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #6
James Wrote:
Code:
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
Quote this message in a reply
James
Unregistered
 
Post: #7
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.
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #8
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
Quote this message in a reply
James
Unregistered
 
Post: #9
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.

Code:
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.


Code:
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.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #10
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.
Quote this message in a reply
James
Unregistered
 
Post: #11
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.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #12
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.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  simple question (private) imaumac 9 3,803 Oct 21, 2008 09:37 PM
Last Post: imaumac
  simple Question about movement bonanza 3 3,035 Oct 17, 2007 11:12 AM
Last Post: bonanza
  Really simple #pragma question WhatMeWorry 9 4,068 Dec 13, 2006 10:15 PM
Last Post: Nick
  Simple CarbonEvent Question Abyssal 3 3,193 Jan 1, 2006 09:53 PM
Last Post: radiance
  NSTimer / animation framerate question MonitorFlickers 5 5,155 Dec 4, 2005 01:10 PM
Last Post: MonitorFlickers