#ifndef RTANIM_H #define RTANIM_H #include /* automatically generated header file */ #define rtANIMSTREAMCURRENTVERSION 0x100 /* Doxygen plugin groups. */ /** * \defgroup rtanim RtAnim * \ingroup animtools * * Animation Toolkit for RenderWare Graphics. */ /** * \ingroup rtanim * Typedef for struct \ref RtAnimAnimation. */ typedef struct RtAnimAnimation RtAnimAnimation; /* * The following CallBacks are needed for each interpolation scheme. * See RtAnimInterpolatorInfo. */ /** * \ingroup rtanim * \ref RtAnimKeyFrameApplyCallBack * defines a callback function for converting * an interpolated animation keyframe into the required result. * * \param result Void pointer to store the output of the conversion. * \param voidIFrame Void pointer to the keyframe and should be cast * to the interpolated keyframe type this callback * is for. */ typedef void (*RtAnimKeyFrameApplyCallBack) (void *result, void *voidIFrame); /** * \ingroup rtanim * \ref RtAnimKeyFrameBlendCallBack * defines a callback function for blending between two * interpolated keyframes by the given blend factor. This is used for * blending the states of two different \ref RtAnimInterpolator objects. * The \ref RtAnimKeyFrameInterpolateCallBack is used for interpolating * actual animation keyframes into an interpolated frame. * * \param voidOut Void pointer to store the output of the blend. * \param voidIn1 Void pointer containing the first input * interpolated keyframe. * \param voidIn2 Void pointer containing the second input * interpolated keyframe. * \param alpha \ref RwReal containing the blend factor. */ typedef void (*RtAnimKeyFrameBlendCallBack) (void *voidOut, void *voidIn1, void *voidIn2, RwReal alpha); /** * \ingroup rtanim * \ref RtAnimKeyFrameInterpolateCallBack * defines a callback function for interpolating between two * animation keyframes according to the given time. The output is * an interpolated frame object residing in an \ref RtAnimInterpolator * and will usually have the same structure as the keyframe apart from * the header data (\ref RtAnimInterpFrameHeader). * * \param voidOut Void pointer for the output of the interpolation. * \param voidIn1 Void pointer containing the first input keyframe. * \param voidIn2 Void pointer containing the second input keyframe. * \param time \ref RwReal containing the time at which to interpolate. */ typedef void (*RtAnimKeyFrameInterpolateCallBack) (void *voidOut, void *voidIn1, void *voidIn2, RwReal time); /** * \ingroup rtanim * \ref RtAnimKeyFrameAddCallBack * defines a callback function for adding two interpolated * keyframes together. This is used when adding the states of two * \ref RtAnimInterpolator objects, such as when adding a delta animation * to a base animation. * * \param voidOut Void pointer for the output interpolated frame. * \param voidIn1 Void pointer containing the first input * interpoalted keyframe. * \param voidIn2 Void pointer containing the second input * interpolated keyframe. */ typedef void (*RtAnimKeyFrameAddCallBack) (void *voidOut, void *voidIn1, void *voidIn2); /** * \ingroup rtanim * \ref RtAnimKeyFrameMulRecipCallBack * defines a callback function for multiplying a keyframe * by the inverse of another keyframe. This is used for creating delta * animations. * * \param voidFrame Void pointer for the keyframe to be modified. * \param voidStart Void pointer for the start keyframe to take the reciprocal of. */ typedef void (*RtAnimKeyFrameMulRecipCallBack) (void *voidFrame, void *voidStart); /** * \ingroup rtanim * \ref RtAnimKeyFrameStreamReadCallBack * defines a callback function for reading in keyframes * from an \ref RwStream for the given animation. * * \param stream Pointer to the \ref RwStream to read the keyframes from. * \param animation Pointer to the \ref RtAnimAnimation to read the keyframes into. * * \return Pointer to the \ref RtAnimAnimation. */ typedef RtAnimAnimation * (*RtAnimKeyFrameStreamReadCallBack) (RwStream *stream, RtAnimAnimation *animation); /** * \ingroup rtanim * \ref RtAnimKeyFrameStreamWriteCallBack * defines a callback function for writing keyframes from the * given animation to an \ref RwStream. * * \param animation Pointer to the \ref RtAnimAnimation to write out from. * \param stream Pointer to the \ref RwStream to write the keyframes to. * * \return \ref RwBool, TRUE if successful. */ typedef RwBool (*RtAnimKeyFrameStreamWriteCallBack) (RtAnimAnimation *animation, RwStream *stream); /** * \ingroup rtanim * \ref RtAnimKeyFrameStreamGetSizeCallBack * defines a callback function for calculating the binary stream * size of keyframe data within an animation. * * \param animation Pointer to the \ref RtAnimAnimation to calculate sizes from. * * \return \ref RwInt32 containing the size, in bytes, of the keyframe data. */ typedef RwInt32 (*RtAnimKeyFrameStreamGetSizeCallBack) (RtAnimAnimation *animation); /** * \ingroup rtanim * \ref RtAnimInterpolatorInfo * Typedef for struct \ref RtAnimInterpolatorInfo */ typedef struct RtAnimInterpolatorInfo RtAnimInterpolatorInfo; /** * \ingroup rtanim * \struct RtAnimInterpolatorInfo * This structure is used to hold information for a keyframe interpolation scheme. * * \see RtAnimRegisterInterpolationScheme * \see RtAnimGetInterpolatorInfo */ struct RtAnimInterpolatorInfo { RwInt32 typeID; /**< The ID of the interpolation scheme. */ RwInt32 keyFrameSize; /**< Size, in bytes, of the keyframe structure. */ RtAnimKeyFrameApplyCallBack keyFrameApplyCB; /**< Pointer to a function that converts a keyframe to the needed * format. This function is never called from the \ref rtanim * toolkit (as the toolit doesn't know the data layout of the * results) but is stored to ease the creation of overloaded * interpolators. */ RtAnimKeyFrameBlendCallBack keyFrameBlendCB; /**< Pointer to a function that blends between two * interpolated keyframes, for the purpose of blending * between the states of two \ref RtAnimInterpolator objects. */ RtAnimKeyFrameInterpolateCallBack keyFrameInterpolateCB; /**< Pointer to a function that interpolates between two keyframes * for a given time in between. */ RtAnimKeyFrameAddCallBack keyFrameAddCB; /**< Pointer to a function that adds two interpolated keyframes * for the purpose of adding the states of two * \ref RtAnimInterpolator objects. */ RtAnimKeyFrameMulRecipCallBack keyFrameMulRecipCB; /**< Pointer to a function that multiplies a keyframe by the * reciprocal of another. */ RtAnimKeyFrameStreamReadCallBack keyFrameStreamReadCB; /**< Pointer to a function that reads the keyframes from a stream * for a given animation. */ RtAnimKeyFrameStreamWriteCallBack keyFrameStreamWriteCB; /**< Pointer to a function that writes the keyframes to a stream for * a given animation. */ RtAnimKeyFrameStreamGetSizeCallBack keyFrameStreamGetSizeCB; /**< Pointer to a function that returns the binary stream size of * the keyframes for a given animation. */ }; /** * \ingroup rtanim * \struct RtAnimAnimation * A keyframed animation consists of an array of keyframe structures, * along with some flags and a duration. * * The keyframes should be presented in the order they are needed * to animate forwards through time. That is, the next keyframe * at some point in the sequence should correspond to the node whose * previous two keyframes are next to expire as an interpolation * pair. * * Put another way, the correct ordering can be achieved by sorting * an unordered keyframe array using the following primary and secondary * sort keys:- * * - time of previous keyframe for node * - node index * * An example is shown in the following diagram, where each vertical bar * indicates a keyframe point in time. The position of the keyframe * within the animation sequence is shown by an index to the left of * each bar. * * \verbatim t=0 t=duration node 0 kf0..| kf3.......| kf8....| kf10....| node 1 kf1..| kf4...| kf6........| kf11....| node 2 kf2..| kf5.....| kf7..| kf9.........| \endverbatim * * Each node MUST have an initial keyframe at time = 0.0, and a terminal * keyframe at time = duration of the animation. * * Pointers link all of the keyframes for a particular node backwards * through time in a list. * * \see RtAnimAnimationCreate */ struct RtAnimAnimation { RtAnimInterpolatorInfo *interpInfo; /**< Pointer to interpolation scheme information */ RwInt32 numFrames; /**< Number of keyframes in the animation */ RwInt32 flags; /**< Specifies details about animation, * relative translation modes etc. */ RwReal duration; /**< Duration of animation in seconds */ void *pFrames; /**< Pointer to the animation keyframes */ }; /** * \ingroup rtanim * \ref RtAnimKeyFrameHeader * Typedef for struct RtAnimKeyFrameHeader */ typedef struct RtAnimKeyFrameHeader RtAnimKeyFrameHeader; /** * \ingroup rtanim * \struct RtAnimKeyFrameHeader * holds header information for a keyframe. All keyframe structures used with * the overloadable interpolation system should start with this data. * * \see RtAnimRegisterInterpolationScheme */ struct RtAnimKeyFrameHeader { void *prevFrame; /**< Previous keyframe for particular hierarchy node */ RwReal time; /**< Time at keyframe */ }; /** * \ingroup rtanim * \ref RtAnimInterpFrameHeader * Typedef for struct RtAnimInterpFrameHeader */ typedef struct RtAnimInterpFrameHeader RtAnimInterpFrameHeader; /** * \ingroup rtanim * \struct RtAnimInterpFrameHeader * is the header for an interpolated animation frame, intermediate * between a keyframe pair. This structure is intentionally the same size as an * \ref RtAnimKeyFrameHeader, so that an interpolated frame and key frame data * block can be otherwise identical. It relies on the * fact that the prevFrame and time fields of a keyframe header are not * relevant to an interpolated frame. These fields should therefore not be * be modified by a custom keyframe interpolator. * * \see RtAnimRegisterInterpolationScheme */ struct RtAnimInterpFrameHeader { RtAnimKeyFrameHeader *keyFrame1; /**< Pointer to the first of the current pair of keyframes in the associated \ref RtAnimAnimation */ RtAnimKeyFrameHeader *keyFrame2; /**< Pointer to the second of the current pair of keyframes in the associated \ref RtAnimAnimation */ }; /** * \ingroup rtanim * \ref RtAnimInterpolator * Typedef for struct \ref RtAnimInterpolator */ typedef struct RtAnimInterpolator RtAnimInterpolator; /** * \ingroup rtanim * \ref RtAnimCallBack * defines a callback function for use with the * \ref RtAnimInterpolatorSetAnimCallBack and * \ref RtAnimInterpolatorSetAnimLoopCallBack functions. * * \param animInstance * A pointer to the \ref RtAnimInterpolator structure. * * \param data Void pointer for user-defined data. * You can use this to pass your own data * structure(s) to the callback function. * * \see RtAnimInterpolatorSetAnimCallBack * \see RtAnimInterpolatorSetAnimLoopCallBack * */ typedef RtAnimInterpolator * (*RtAnimCallBack) (RtAnimInterpolator *animInstance, void *data); /** * \ingroup rtanim * \struct RtAnimInterpolator * holds the current state for a particular instance of an animation, * corresponding to a specific point in time. * * The current interpolated keyframes are stored in an array after the * end of this structure. For advanced use, these may be accessed * using the macro rtANIMGETINTERPFRAME(interpolator, nodeIndex) * which takes a pointer to the interpolator and the node index * for the interpolated keyframe required. * * \see \ref RtAnimInterpolatorCreate * \see \ref RtAnimInterpolatorDestroy * \see \ref RtAnimInterpolatorSetCurrentAnim * \see \ref RtAnimInterpolatorGetCurrentAnim * \see \ref RtAnimInterpolatorSetKeyFrameCallBacks * \see \ref RtAnimInterpolatorSetAnimLoopCallBack * \see \ref RtAnimInterpolatorSetAnimCallBack * \see \ref RtAnimInterpolatorCopy * \see \ref RtAnimInterpolatorSubAnimTime * \see \ref RtAnimInterpolatorAddAnimTime * \see \ref RtAnimInterpolatorSetCurrentTime * \see \ref RtAnimCallBack */ struct RtAnimInterpolator { RtAnimAnimation *pCurrentAnim; /**< Current \ref RtAnimAnimation applied */ RwReal currentTime; /**< Current animation time */ void *pNextFrame; /**< Next animation keyframe to be played */ RtAnimCallBack pAnimCallBack; /**< Animation callback function pointer */ void *pAnimCallBackData; /**< Animation callback function user data */ RwReal animCallBackTime; /**< Trigger time for callback function */ RtAnimCallBack pAnimLoopCallBack; /**< Animation loop callback function pointer */ void *pAnimLoopCallBackData; /**< Animation loop callback function data */ RwInt32 maxKeyFrameSize; /**< Maximum size of keyframes usable on * this animation (set at creation time) */ RwInt32 currentKeyFrameSize; /**< Size of keyframes in the current * animation */ RwInt32 numNodes; /**< Number of nodes driven by the animation */ RwBool isSubInterpolator; /**< Internal use */ RwInt32 offsetInParent; /**< Internal use */ RtAnimInterpolator *parentAnimation; /**< Internal use */ RtAnimKeyFrameApplyCallBack keyFrameApplyCB; /**< Internal use */ RtAnimKeyFrameBlendCallBack keyFrameBlendCB; /**< Internal use */ RtAnimKeyFrameInterpolateCallBack keyFrameInterpolateCB; /**< Internal use */ RtAnimKeyFrameAddCallBack keyFrameAddCB; /**< Internal use */ }; /* Access to array of interpolated frames occupying a block of memory * after the end of the RtAnimInterpolator structure. */ #define rtANIMGETINTERPFRAME( anim, nodeIndex ) \ ( (void *)( ( (RwUInt8 *)&(anim[1]) + \ ((nodeIndex) * \ anim->currentKeyFrameSize) ) ) ) #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Engine functions */ extern void RtAnimAnimationFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc ); extern RwBool RtAnimInitialize(void); extern RwBool RtAnimRegisterInterpolationScheme(RtAnimInterpolatorInfo *interpolatorInfo); extern RtAnimInterpolatorInfo * RtAnimGetInterpolatorInfo(RwInt32 typeID); /* RtAnimAnimation */ extern RtAnimAnimation * RtAnimAnimationCreate(RwInt32 typeID, RwInt32 numFrames, RwInt32 flags, RwReal duration); extern RtAnimAnimation * RtAnimAnimationDestroy(RtAnimAnimation *animation); extern RtAnimAnimation * RtAnimAnimationRead(const RwChar * filename); extern RwBool RtAnimAnimationWrite(RtAnimAnimation *animation, const RwChar * filename); extern RtAnimAnimation * RtAnimAnimationStreamRead(RwStream *stream); extern RwBool RtAnimAnimationStreamWrite(RtAnimAnimation *animation, RwStream *stream); extern RwInt32 RtAnimAnimationStreamGetSize(RtAnimAnimation *animation); extern RwUInt32 RtAnimAnimationGetNumNodes(RtAnimAnimation *animation); #ifdef RWDEBUG extern RwInt32 RtAnimAnimationGetTypeID(RtAnimAnimation *animation); #else /* RWDEBUG */ #define RtAnimAnimationGetTypeID(animation) \ (animation->interpInfo->typeID) #endif /* RWDEBUG */ /* RtAnimInterpolator */ extern RtAnimInterpolator * RtAnimInterpolatorCreate(RwInt32 numNodes, RwInt32 maxKeyFrameSize); extern void RtAnimInterpolatorDestroy(RtAnimInterpolator *anim); extern RwBool RtAnimInterpolatorSetCurrentAnim(RtAnimInterpolator *animI, RtAnimAnimation *anim); #ifdef RWDEBUG extern RtAnimAnimation * RtAnimInterpolatorGetCurrentAnim(RtAnimInterpolator *animI); #else /* RWDEBUG */ #define RtAnimInterpolatorGetCurrentAnim(animI) \ (animI->pCurrentAnim) #endif /* RWDEBUG */ extern RwBool RtAnimInterpolatorSetKeyFrameCallBacks(RtAnimInterpolator *anim, RwInt32 keyFrameTypeID); extern void RtAnimInterpolatorSetAnimLoopCallBack(RtAnimInterpolator *anim, RtAnimCallBack callBack, void *data ); extern void RtAnimInterpolatorSetAnimCallBack(RtAnimInterpolator *anim, RtAnimCallBack callBack, RwReal time, void *data ); extern RwBool RtAnimInterpolatorCopy(RtAnimInterpolator *outAnim, RtAnimInterpolator *inAnim); extern RwBool RtAnimInterpolatorSubAnimTime(RtAnimInterpolator *anim, RwReal time); extern RwBool RtAnimInterpolatorAddAnimTime(RtAnimInterpolator *anim, RwReal time); extern RwBool RtAnimInterpolatorSetCurrentTime(RtAnimInterpolator *anim, RwReal time); extern RwBool RtAnimAnimationMakeDelta(RtAnimAnimation *animation, RwInt32 numNodes, RwReal time); extern RwBool RtAnimInterpolatorBlend(RtAnimInterpolator *outAnim, RtAnimInterpolator *inAnim1, RtAnimInterpolator *inAnim2, RwReal alpha); extern RwBool RtAnimInterpolatorAddTogether(RtAnimInterpolator *outAnim, RtAnimInterpolator *inAnim1, RtAnimInterpolator *inAnim2); #define RtAnimKeyFrameApplyMacro(animation, out, in) \ MACRO_START \ { \ (anim)->keyFrameApplyCB((out), (in1), (in2), (time)); \ } \ MACRO_STOP #define RtAnimKeyFrameInterpolateMacro(anim, out, in1, in2, time) \ MACRO_START \ { \ (anim)->keyFrameInterpolateCB((out), (in1), (in2), (time)); \ } \ MACRO_STOP #define RtAnimKeyFrameBlendMacro(anim, out, in1, in2, fAlpha) \ MACRO_START \ { \ (anim)->keyFrameBlendCB((out), (in1), (in2), (fAlpha)); \ } \ MACRO_STOP #define RtAnimKeyFrameAddTogetherMacro(anim, out, in1, in2) \ MACRO_START \ { \ (anim)->keyFrameAddCB((out), (in1), (in2)); \ } \ MACRO_STOP #ifdef RWDEBUG extern void RtAnimKeyFrameApply(RtAnimInterpolator *animation, void *result, void *iFrame); extern void RtAnimKeyFrameInterpolate(RtAnimInterpolator *animation, void *out, void *in1, void *in2, RwReal time); extern void RtAnimKeyFrameBlend(RtAnimInterpolator *animation, void *out, void *in1, void *in2, RwReal alpha); extern void RtAnimKeyFrameAddTogether(RtAnimInterpolator *animation, void *out, void *in1, void *in2); #else /* RWDEBUG */ #define RtAnimKeyFrameApply(animation, out, in) \ RtAnimKeyFrameApplyMacro(animation, out, in) #define RtAnimKeyFrameInterpolate(animation, out, in1, in2, time) \ RtAnimKeyFrameInterpolateMacro(animation, out, in1, in2, time) #define RtAnimKeyFrameBlend(animation, out, in1, in2, alpha) \ RtAnimKeyFrameBlendMacro(animation, out, in1, in2, alpha) #define RtAnimKeyFrameAddTogether(animation, out, in1, in2) \ RtAnimKeyFrameAddTogetherMacro(animation, out, in1, in2) #endif /* RWDEBUG */ extern RtAnimInterpolator * RtAnimInterpolatorCreateSubInterpolator( RtAnimInterpolator *parentAnim, RwInt32 startNode, RwInt32 numNodes, RwInt32 maxKeyFrameSize); extern RwBool RtAnimInterpolatorBlendSubInterpolator(RtAnimInterpolator *outAnim, RtAnimInterpolator *inAnim1, RtAnimInterpolator *inAnim2, RwReal alpha); extern RwBool RtAnimInterpolatorAddSubInterpolator(RtAnimInterpolator *outAnim, RtAnimInterpolator *mainAnim, RtAnimInterpolator *subAnim); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* RTANIM_H */