2021-09-15 23:24:19 +00:00
# ifndef Z64_ANIMATION_H
# define Z64_ANIMATION_H
2020-03-23 01:24:00 +00:00
2020-10-03 15:22:44 +00:00
# include "ultra64.h"
# include "z64dma.h"
# include "z64math.h"
2020-03-23 01:24:00 +00:00
struct GlobalContext ;
struct Actor ;
2020-12-02 03:19:56 +00:00
struct SkelAnime ;
# define LIMB_DONE 0xFF
# define ANIMATION_ENTRY_MAX 50
2020-12-29 22:46:46 +00:00
# define ANIM_FLAG_UPDATEY (1 << 1)
# define ANIM_FLAG_NOMOVE (1 << 4)
2022-02-12 19:50:06 +00:00
enum AnimationModes {
2020-12-29 22:46:46 +00:00
/* 0 */ ANIMMODE_LOOP ,
/* 1 */ ANIMMODE_LOOP_INTERP ,
/* 2 */ ANIMMODE_ONCE ,
/* 3 */ ANIMMODE_ONCE_INTERP ,
/* 4 */ ANIMMODE_LOOP_PARTIAL ,
/* 5 */ ANIMMODE_LOOP_PARTIAL_INTERP
2022-02-12 19:50:06 +00:00
} ;
2020-12-29 22:46:46 +00:00
2022-02-12 19:50:06 +00:00
enum AnimationTapers {
2020-12-29 22:46:46 +00:00
/* -1 */ ANIMTAPER_DECEL = - 1 ,
/* 0 */ ANIMTAPER_NONE ,
/* 1 */ ANIMTAPER_ACCEL
2022-02-12 19:50:06 +00:00
} ;
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct StandardLimb {
2020-12-02 03:19:56 +00:00
/* 0x00 */ Vec3s jointPos ; // Root is position in model space, children are relative to parent
/* 0x06 */ u8 child ;
/* 0x07 */ u8 sibling ;
/* 0x08 */ Gfx * dList ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct LodLimb {
2020-12-02 03:19:56 +00:00
/* 0x00 */ Vec3s jointPos ; // Root is position in model space, children are relative to parent
/* 0x06 */ u8 child ;
/* 0x07 */ u8 sibling ;
/* 0x08 */ Gfx * dLists [ 2 ] ; // Near and far
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-03-25 15:51:25 +00:00
2022-02-12 19:50:06 +00:00
struct SkinLimb {
2020-12-02 03:19:56 +00:00
/* 0x00 */ Vec3s jointPos ; // Root is position in model space, children are relative to parent
/* 0x06 */ u8 child ;
/* 0x07 */ u8 sibling ;
2020-12-29 05:30:23 +00:00
/* 0x08 */ s32 unk_8 ; // Type of data contained in segment
2021-02-12 19:41:34 +00:00
/* 0x0C */ void * segment ; // Segment address of data. Currently unclear what.
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct LegacyLimb {
2021-06-14 18:12:34 +00:00
/* 0x000 */ Gfx * dList ;
/* 0x004 */ Vec3f trans ;
/* 0x010 */ Vec3s rot ;
/* 0x018 */ struct LegacyLimb * sibling ;
/* 0x01C */ struct LegacyLimb * child ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x20
2021-06-14 18:12:34 +00:00
2020-12-02 03:19:56 +00:00
// Model has limbs with only rigid meshes
2022-02-12 19:50:06 +00:00
struct SkeletonHeader {
2020-12-02 03:19:56 +00:00
/* 0x00 */ void * * segment ;
/* 0x04 */ u8 limbCount ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x8
2020-03-23 01:24:00 +00:00
2020-12-02 03:19:56 +00:00
// Model has limbs with flexible meshes
2022-02-12 19:50:06 +00:00
struct FlexSkeletonHeader {
2020-12-02 03:19:56 +00:00
/* 0x00 */ SkeletonHeader sh ;
/* 0x08 */ u8 dListCount ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-03-23 01:24:00 +00:00
2020-12-29 22:46:46 +00:00
// Index into the frame data table.
2022-02-12 19:50:06 +00:00
struct JointIndex {
2020-12-29 22:46:46 +00:00
/* 0x00 */ u16 x ;
/* 0x02 */ u16 y ;
/* 0x04 */ u16 z ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x06
2020-03-25 15:51:25 +00:00
2022-02-12 19:50:06 +00:00
struct AnimationHeaderCommon {
2020-12-29 22:46:46 +00:00
/* 0x00 */ s16 frameCount ;
2022-02-12 19:50:06 +00:00
} ;
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct LinkAnimationHeader {
2020-12-29 22:46:46 +00:00
/* 0x00 */ AnimationHeaderCommon common ;
2021-11-09 02:15:37 +00:00
/* 0x04 */ void * segment ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x8
2020-12-02 03:19:56 +00:00
2022-02-12 19:50:06 +00:00
struct AnimationHeader {
2020-12-29 22:46:46 +00:00
/* 0x00 */ AnimationHeaderCommon common ;
2021-11-30 23:40:42 +00:00
/* 0x04 */ s16 * frameData ; // "tbl"
2020-12-29 22:46:46 +00:00
/* 0x08 */ JointIndex * jointIndices ; // "ref_tbl"
/* 0x0C */ u16 staticIndexMax ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-12-29 22:46:46 +00:00
// Unused
2022-02-12 19:50:06 +00:00
struct JointKey {
2020-12-29 22:46:46 +00:00
/* 0x00 */ s16 xMax ;
/* 0x02 */ s16 x ;
/* 0x04 */ s16 yMax ;
/* 0x06 */ s16 y ;
/* 0x08 */ s16 zMax ;
2021-06-14 18:12:34 +00:00
/* 0x0A */ s16 z ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x0C
2020-12-29 22:46:46 +00:00
// Unused
2022-02-12 19:50:06 +00:00
struct LegacyAnimationHeader {
2020-12-29 22:46:46 +00:00
/* 0x00 */ s16 frameCount ;
/* 0x02 */ s16 limbCount ;
/* 0x04 */ s16 * frameData ;
/* 0x08 */ JointKey * jointKey ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-12-29 22:46:46 +00:00
2020-12-02 03:19:56 +00:00
typedef s32 ( * OverrideLimbDrawOpa ) ( struct GlobalContext * globalCtx , s32 limbIndex , Gfx * * dList , Vec3f * pos , Vec3s * rot ,
void * ) ;
typedef void ( * PostLimbDrawOpa ) ( struct GlobalContext * globalCtx , s32 limbIndex , Gfx * * dList , Vec3s * rot , void * ) ;
typedef s32 ( * OverrideLimbDraw ) ( struct GlobalContext * globalCtx , s32 limbIndex , Gfx * * dList , Vec3f * pos , Vec3s * rot ,
void * , Gfx * * gfx ) ;
2020-12-29 22:46:46 +00:00
typedef void ( * PostLimbDraw ) ( struct GlobalContext * globalCtx , s32 limbIndex , Gfx * * dList , Vec3s * rot , void * , Gfx * * gfx ) ;
2020-12-02 03:19:56 +00:00
2022-02-12 19:50:06 +00:00
enum AnimationType {
2020-12-29 22:46:46 +00:00
ANIMENTRY_LOADFRAME ,
ANIMENTRY_COPYALL ,
ANIMENTRY_INTERP ,
ANIMENTRY_COPYTRUE ,
ANIMENTRY_COPYFALSE ,
ANIMENTRY_MOVEACTOR
2022-02-12 19:50:06 +00:00
} ;
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimEntryLoadFrame {
2020-03-24 16:52:12 +00:00
/* 0x000 */ DmaRequest req ;
/* 0x020 */ OSMesgQueue msgQueue ;
/* 0x038 */ OSMesg msg ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x3C
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimEntryCopyAll {
2020-12-29 22:46:46 +00:00
/* 0x000 */ u8 queueFlag ;
2020-03-24 16:52:12 +00:00
/* 0x001 */ u8 vecCount ;
/* 0x004 */ Vec3s * dst ;
/* 0x008 */ Vec3s * src ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimEntryInterp {
2020-12-29 22:46:46 +00:00
/* 0x000 */ u8 queueFlag ;
/* 0x001 */ u8 vecCount ;
/* 0x004 */ Vec3s * base ;
/* 0x008 */ Vec3s * mod ;
/* 0x00C */ f32 weight ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimEntryCopyTrue {
2020-12-29 22:46:46 +00:00
/* 0x000 */ u8 queueFlag ;
2020-03-24 16:52:12 +00:00
/* 0x001 */ u8 vecCount ;
/* 0x004 */ Vec3s * dst ;
/* 0x008 */ Vec3s * src ;
2022-03-01 15:39:16 +00:00
/* 0x00C */ const u8 * copyFlag ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimEntryCopyFalse {
2020-12-29 22:46:46 +00:00
/* 0x000 */ u8 queueFlag ;
2020-03-24 16:52:12 +00:00
/* 0x001 */ u8 vecCount ;
/* 0x004 */ Vec3s * dst ;
/* 0x008 */ Vec3s * src ;
2022-03-01 15:39:16 +00:00
/* 0x00C */ const u8 * copyFlag ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimEntryMoveActor {
2020-03-24 16:52:12 +00:00
/* 0x000 */ struct Actor * actor ;
2020-12-02 03:19:56 +00:00
/* 0x004 */ struct SkelAnime * skelAnime ;
2020-03-24 16:52:12 +00:00
/* 0x008 */ f32 unk_08 ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
union AnimationEntryData {
2020-12-29 22:46:46 +00:00
AnimEntryLoadFrame load ;
AnimEntryCopyAll copy ;
AnimEntryInterp interp ;
AnimEntryCopyTrue copy1 ;
AnimEntryCopyFalse copy0 ;
AnimEntryMoveActor move ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x3C
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimationEntry {
2020-12-02 03:19:56 +00:00
/* 0x00 */ u8 type ;
/* 0x04 */ AnimationEntryData data ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x40
2020-03-23 01:24:00 +00:00
2022-02-12 19:50:06 +00:00
struct AnimationContext {
2020-03-23 01:24:00 +00:00
s16 animationCount ;
2020-03-25 15:51:25 +00:00
AnimationEntry entries [ ANIMATION_ENTRY_MAX ] ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC84
2020-03-23 01:24:00 +00:00
2020-12-02 03:19:56 +00:00
typedef void ( * AnimationEntryCallback ) ( struct GlobalContext * globalCtx , AnimationEntryData * data ) ;
2020-03-23 21:31:24 +00:00
2020-05-19 20:27:25 +00:00
// fcurve_skelanime structs
2022-02-12 19:50:06 +00:00
struct TransformData {
2020-05-19 20:27:25 +00:00
/* 0x0000 */ u16 unk_00 ; // appears to be flags
/* 0x0002 */ s16 unk_02 ;
/* 0x0004 */ s16 unk_04 ;
/* 0x0006 */ s16 unk_06 ;
/* 0x0008 */ f32 unk_08 ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-05-19 20:27:25 +00:00
2022-02-12 19:50:06 +00:00
struct TransformUpdateIndex {
2020-05-19 20:27:25 +00:00
/* 0x0000 */ u8 * refIndex ;
2020-10-03 15:22:44 +00:00
/* 0x0004 */ TransformData * transformData ;
2020-05-19 20:27:25 +00:00
/* 0x0008 */ s16 * copyValues ;
/* 0x000C */ s16 unk_0C ;
2021-10-03 03:17:09 +00:00
/* 0x000E */ s16 unk_0E ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-05-19 20:27:25 +00:00
2022-02-12 19:50:06 +00:00
struct SkelCurveLimb {
2020-05-19 20:27:25 +00:00
/* 0x0000 */ u8 firstChildIdx ;
/* 0x0001 */ u8 nextLimbIdx ;
/* 0x0004 */ Gfx * dList [ 2 ] ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-05-19 20:27:25 +00:00
2022-02-12 19:50:06 +00:00
struct SkelCurveLimbList {
2020-05-19 20:27:25 +00:00
/* 0x0000 */ SkelCurveLimb * * limbs ;
/* 0x0004 */ u8 limbCount ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x8
2020-05-19 20:27:25 +00:00
2022-02-12 19:50:06 +00:00
struct LimbTransform {
2020-05-19 20:27:25 +00:00
/* 0x0000 */ Vec3s scale ;
/* 0x0006 */ Vec3s rot ;
/* 0x000C */ Vec3s pos ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x12
2020-05-19 20:27:25 +00:00
2022-02-12 19:50:06 +00:00
struct SkelAnimeCurve {
2020-05-19 20:27:25 +00:00
/* 0x0000 */ u8 limbCount ;
/* 0x0004 */ SkelCurveLimb * * limbList ;
2020-10-03 15:22:44 +00:00
/* 0x0008 */ TransformUpdateIndex * transUpdIdx ;
2020-05-19 20:27:25 +00:00
/* 0x000C */ f32 unk_0C ; // seems to be unused
/* 0x0010 */ f32 animFinalFrame ;
/* 0x0014 */ f32 animSpeed ;
/* 0x0018 */ f32 animCurFrame ;
/* 0x001C */ LimbTransform * transforms ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x20
2020-05-19 20:27:25 +00:00
2020-12-26 00:24:16 +00:00
typedef s32 ( * OverrideCurveLimbDraw ) ( struct GlobalContext * globalCtx , SkelAnimeCurve * skelCurve , s32 limbIndex , void * ) ;
typedef void ( * PostCurveLimbDraw ) ( struct GlobalContext * globalCtx , SkelAnimeCurve * skelCurve , s32 limbIndex , void * ) ;
2020-12-02 03:19:56 +00:00
2020-12-29 22:46:46 +00:00
typedef s32 ( * AnimUpdateFunc ) ( ) ;
2020-12-02 03:19:56 +00:00
2022-02-12 19:50:06 +00:00
struct SkelAnime {
2020-12-29 22:46:46 +00:00
/* 0x00 */ u8 limbCount ; // Number of limbs in the skeleton
/* 0x01 */ u8 mode ; // 0: loop, 2: play once, 4: partial loop. +1 to interpolate between frames.
/* 0x02 */ u8 dListCount ; // Number of display lists in a flexible skeleton
/* 0x03 */ s8 taper ; // Tapering to use when morphing between animations. Only used by Door_Warp1.
/* 0x04 */ void * * skeleton ; // An array of pointers to limbs. Can be StandardLimb, LodLimb, or SkinLimb.
/* 0x08 */ void * animation ; // Can be an AnimationHeader or LinkAnimationHeader.
/* 0x0C */ f32 startFrame ; // In mode 4, start of partial loop.
/* 0x10 */ f32 endFrame ; // In mode 2, Update returns true when curFrame is equal to this. In mode 4, end of partial loop.
/* 0x14 */ f32 animLength ; // Total number of frames in the current animation's file.
/* 0x18 */ f32 curFrame ; // Current frame in the animation
/* 0x1C */ f32 playSpeed ; // Multiplied by R_UPDATE_RATE / 3 to get the animation's frame rate.
/* 0x20 */ Vec3s * jointTable ; // Current translation of model and rotations of all limbs
/* 0x24 */ Vec3s * morphTable ; // Table of values used to morph between animations
/* 0x28 */ f32 morphWeight ; // Weight of the current animation morph as a fraction in [0,1]
/* 0x2C */ f32 morphRate ; // Reciprocal of the number of frames in the morph
2022-02-12 19:50:06 +00:00
/* 0x30 */ s32 ( * update ) ( GlobalContext * , SkelAnime * ) ; // Can be Loop, Partial loop, Play once, Morph, or Tapered morph. Link only has Loop, Play once, and Morph
2020-12-29 22:46:46 +00:00
/* 0x34 */ s8 initFlags ; // Flags used when initializing Link's skeleton
2021-11-30 23:40:42 +00:00
/* 0x35 */ u8 moveFlags ; // Flags used for animations that move the actor in worldspace.
2020-12-29 22:46:46 +00:00
/* 0x36 */ s16 prevRot ; // Previous rotation in worldspace.
/* 0x38 */ Vec3s prevTransl ; // Previous modelspace translation.
/* 0x3E */ Vec3s baseTransl ; // Base modelspace translation.
2022-02-12 19:50:06 +00:00
} ; // size = 0x44
2020-05-19 20:27:25 +00:00
2022-02-12 19:50:06 +00:00
struct Struct_800A57C0 {
2020-12-29 05:30:23 +00:00
/* 0x000 */ u16 unk_0 ;
2021-02-12 19:41:34 +00:00
/* 0x002 */ s16 unk_2 ;
/* 0x004 */ s16 unk_4 ;
2020-12-29 05:30:23 +00:00
/* 0x006 */ s8 unk_6 ;
/* 0x007 */ s8 unk_7 ;
/* 0x008 */ s8 unk_8 ;
2021-02-12 19:41:34 +00:00
/* 0x009 */ u8 unk_9 ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xA
2020-12-29 05:30:23 +00:00
2022-02-12 19:50:06 +00:00
struct Struct_800A598C_2 {
2020-12-29 05:30:23 +00:00
/* 0x000 */ u8 unk_0 ;
/* 0x002 */ s16 x ;
/* 0x004 */ s16 y ;
/* 0x006 */ s16 z ;
/* 0x008 */ u8 unk_8 ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xA
2020-12-29 05:30:23 +00:00
2022-02-12 19:50:06 +00:00
struct Struct_800A598C {
2021-02-12 19:41:34 +00:00
/* 0x000 */ u16 unk_0 ;
2020-12-29 05:30:23 +00:00
/* 0x002 */ u16 unk_2 ;
2021-02-12 19:41:34 +00:00
/* 0x004 */ u16 unk_4 ;
/* 0x008 */ Struct_800A57C0 * unk_8 ;
/* 0x00C */ Struct_800A598C_2 * unk_C ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x10
2020-12-29 05:30:23 +00:00
2022-02-12 19:50:06 +00:00
struct Struct_800A5E28 {
2020-12-29 05:30:23 +00:00
/* 0x000 */ u16 unk_0 ;
/* 0x002 */ u16 unk_2 ;
2021-02-12 19:41:34 +00:00
/* 0x004 */ Struct_800A598C * unk_4 ;
/* 0x008 */ Gfx * unk_8 ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-12-29 05:30:23 +00:00
2022-02-12 19:50:06 +00:00
struct SkinAvb {
2020-12-29 05:30:23 +00:00
/* 0x000 */ u8 unk_0 ;
/* 0x004 */ Vtx * buf [ 2 ] ;
2022-02-12 19:50:06 +00:00
} ; // size = 0xC
2020-12-29 05:30:23 +00:00
2022-02-12 19:50:06 +00:00
struct PSkinAwb {
2020-12-29 05:30:23 +00:00
/* 0x000 */ SkeletonHeader * skeletonHeader ;
/* 0x004 */ MtxF mtx ;
/* 0x044 */ s32 avbCount ;
/* 0x048 */ SkinAvb * avbTbl ;
/* 0x04C */ SkelAnime skelAnime ;
2022-02-12 19:50:06 +00:00
} ; // size = 0x90
2020-12-29 05:30:23 +00:00
typedef void ( * SkinCallback ) ( struct Actor * , struct GlobalContext * , PSkinAwb * ) ;
typedef s32 ( * SkinCallback2 ) ( struct Actor * , struct GlobalContext * , s32 , PSkinAwb * ) ;
2020-03-23 21:31:24 +00:00
# endif