/* * RsdAnim Animation Library v2 */ #include #include #include #include #include #include "rsdanim.h" /* * Initialisation * --- * Call this once for every object you want to animate. It preserves a copy of your baseframe * vertices so you can restore them at any point later on... * PARAMETERS: * obj : pointer to the object (already linked & stuff) * mime : pointer to the MIME_MOVEMENT structure generated by RsdAnim (this holds the animation sequence) * mh : pointer to a MIME_HANDLE for InitMIMe to fill in for you */ TMD_OBJECT *InitMIMe(GsDOBJ2 *obj, MIME_MOVEMENT *mime, MIME_HANDLE *mh) { TMD_OBJECT *o=(TMD_OBJECT*)obj->tmd; mh->movement=mime; mh->vectors=(SVECTOR*)o->vert_top; mh->n_vert=o->n_vert; mh->frame=0; mh->base_vectors=malloc(sizeof(SVECTOR)*o->n_vert); mh->step=0; memcpy(mh->base_vectors,mh->vectors,sizeof(SVECTOR)*o->n_vert); return o; } /* * Extended Initialise *---- * If you've got an object doing several movements (say, animating a human body which can walk or * jump or punch, etc) use InitMIMe() for the first movement and InitMIMeX() for all the rest * this simply avoids making repeated copies of the baseframe vertices (you only need the one, and * all movements of an object can reset to baseframe from the one copy). * PARAMETERS: * obj : pointer to the object (already linked & stuff) * mime : pointer to the MIME_MOVEMENT structure generated by RsdAnim * mh : pointer to a MIME_HANDLE for InitMIMe to fill in for you * existing : pointer to a MIME_HANDLE for a movement on off this object already filled in by InitMIMe() */ TMD_OBJECT *InitMIMeX(GsDOBJ2 *obj, MIME_MOVEMENT *mime, MIME_HANDLE *mh, MIME_HANDLE *existing) { TMD_OBJECT *o=(TMD_OBJECT*)obj->tmd; mh->movement=mime; mh->vectors=(SVECTOR*)o->vert_top; mh->n_vert=o->n_vert; mh->frame=0; mh->base_vectors=existing->base_vectors; mh->step=0; return o; } /* * Release memory allocated to a MIME_HANDLE *---- * PARAMETERS: * mh : pointer to the handle to release */ void ReleaseMIMe(MIME_HANDLE *mh) { free(mh->base_vectors); mh->base_vectors=NULL; } /* * Link Binary MIMe file (converts offsets to pointers for a loaded file) *---- * PARAMETERS: * m : pointer to a Binary MIMe file in memory (a .MIM file) * Returns: * pointer to MIMe info */ MIME_MOVEMENT *LinkMIMe(unsigned long *m) { unsigned long b=(unsigned long)m; int f; for(f=0; m[f]!=0; f+=2) m[f]=m[f]+b; return (MIME_MOVEMENT*)b; } /* * Reset Animation to baseframe *---- * PARAMETERS: * mh : pointer to a valid MIME_HANDLE */ void ResetMIMe(MIME_HANDLE *mh) { mh->frame=mh->step=0; memcpy(mh->vectors,mh->base_vectors,sizeof(SVECTOR)*mh->n_vert); } /* * Actually do an animation. *------ * Each time DoMIMe() is called, the model will step one frame through the animation sequence. * Simply call this once per frame in your display loop and GsSortObject4() the object as normal. * PARAMETERS: * mh : pointer to a valid MIME_HANDLE * RETURNS: * 0 : animation sequence finished * 1 : animation sequence still running */ int DoMIMe(MIME_HANDLE *mh) { if(mh->frame++>mh->movement[mh->step].frames) { mh->step++; mh->frame=0; } if(mh->movement[mh->step].mime_data==NULL) { mh->step--; return 0; } gteMIMefunc(mh->vectors,mh->movement[mh->step].mime_data,mh->n_vert,mh->movement[mh->step].scaler); return 1; }