2021-09-22 13:17:46 +02:00
|
|
|
#ifndef _MODEL_H_
|
|
|
|
#define _MODEL_H_
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
typedef union ModelNodePropertyData {
|
|
|
|
s32 s;
|
|
|
|
f32 f;
|
2023-02-25 09:30:02 +01:00
|
|
|
void* p;
|
2021-09-22 13:17:46 +02:00
|
|
|
} ModelNodePropertyData;
|
|
|
|
|
2022-09-08 14:21:07 +02:00
|
|
|
// In memory this is a list of ModelNodeProperty, but due to the way it uses
|
|
|
|
// the fields (storing into the "type" field) we decided to make a struct for this
|
|
|
|
typedef struct ModelBoundingBox {
|
|
|
|
/* 0x00 */ s32 key; // MODEL_PROP_KEY_BOUNDING_BOX
|
|
|
|
/* 0x04 */ s32 halfSizeX;
|
|
|
|
/* 0x08 */ f32 minX;
|
|
|
|
/* 0x0C */ char unk_0C[0x04];
|
|
|
|
/* 0x10 */ s32 halfSizeY;
|
|
|
|
/* 0x14 */ f32 minY;
|
|
|
|
/* 0x18 */ char unk_18[0x04];
|
|
|
|
/* 0x1C */ s32 halfSizeZ;
|
|
|
|
/* 0x20 */ f32 minZ;
|
|
|
|
/* 0x24 */ char unk_24[0x8];
|
|
|
|
/* 0x2C */ f32 maxX;
|
|
|
|
/* 0x30 */ char unk_30[0x8];
|
|
|
|
/* 0x38 */ f32 maxY;
|
|
|
|
/* 0x3C */ char unk_3C[0x8];
|
|
|
|
/* 0x44 */ f32 maxZ;
|
|
|
|
} ModelBoundingBox; // size = 0x48?
|
|
|
|
|
2021-09-22 13:17:46 +02:00
|
|
|
typedef struct ModelNodeProperty {
|
|
|
|
/* 0x0 */ s32 key;
|
|
|
|
/* 0x4 */ s32 dataType;
|
|
|
|
/* 0x8 */ ModelNodePropertyData data;
|
|
|
|
} ModelNodeProperty; // size = 0xC;
|
|
|
|
|
2023-11-10 06:19:40 +01:00
|
|
|
typedef struct ModelGroupData {
|
|
|
|
/* 0x00 */ Mtx* transformMatrix;
|
|
|
|
/* 0x04 */ Lightsn* lightingGroup;
|
|
|
|
/* 0x08 */ s32 numLights;
|
|
|
|
/* 0x0C */ s32 numChildren;
|
|
|
|
/* 0x10 */ struct ModelNode** childList;
|
|
|
|
} ModelGroupData; // size = 0x14
|
|
|
|
|
|
|
|
typedef struct ModelDisplayData {
|
|
|
|
/* 0x0 */ Gfx* displayList;
|
|
|
|
/* 0x4 */ char unk_04[0x4];
|
|
|
|
} ModelDisplayData; // size = 0x8
|
|
|
|
|
2021-09-22 13:17:46 +02:00
|
|
|
typedef struct ModelNode {
|
|
|
|
/* 0x00 */ s32 type; /* 2 = model */
|
|
|
|
/* 0x04 */ ModelDisplayData* displayData;
|
|
|
|
/* 0x08 */ s32 numProperties;
|
|
|
|
/* 0x0C */ ModelNodeProperty* propertyList;
|
|
|
|
/* 0x10 */ struct ModelGroupData* groupData;
|
|
|
|
} ModelNode; // size = 0x14
|
|
|
|
|
|
|
|
typedef struct Model {
|
|
|
|
/* 0x00 */ u16 flags;
|
|
|
|
/* 0x02 */ u16 modelID;
|
2023-07-18 11:07:58 +02:00
|
|
|
/* 0x04 */ Mtx* bakedMtx; // pointer to stack-allocated copy of matrix supplied by the shape file for this model
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0x08 */ ModelNode* modelNode;
|
|
|
|
/* 0x0C */ ModelGroupData* groupData;
|
2023-07-18 11:07:58 +02:00
|
|
|
/* 0x10 */ Mtx* finalMtx; // the matrix actually used while building the display list
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0x14 */ char unk_14[4];
|
2023-07-18 11:07:58 +02:00
|
|
|
/* 0x18 */ Mtx savedMtx;
|
|
|
|
/* 0x58 */ Matrix4f userTransformMtx; // provided for user code to apply an additional multiplicative transformation
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0x98 */ Vec3f center;
|
|
|
|
/* 0xA4 */ u8 texPannerID;
|
2021-11-19 15:31:28 +01:00
|
|
|
/* 0xA5 */ u8 customGfxIndex;
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0xA6 */ s8 renderMode;
|
2023-07-18 11:07:58 +02:00
|
|
|
/* 0xA7 */ u8 matrixFreshness;
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0xA8 */ u8 textureID;
|
2021-11-19 15:31:28 +01:00
|
|
|
/* 0xA9 */ s8 textureVariation;
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0xAA */ char unk_AA[6];
|
|
|
|
} Model; // size = 0xB0
|
|
|
|
|
|
|
|
typedef struct ModelTransformGroup {
|
|
|
|
/* 0x00 */ u16 flags;
|
|
|
|
/* 0x02 */ u16 groupModelID;
|
2023-07-18 11:07:58 +02:00
|
|
|
/* 0x04 */ Mtx* bakedMtx; // would point to copy of matrix from shape file, but seems to always be NULL.
|
|
|
|
/* 0x08 */ ModelNode* baseModelNode;
|
|
|
|
/* 0x0C */ Mtx* finalMtx; // the matrix actually used while building the display list
|
|
|
|
/* 0x10 */ Mtx savedMtx;
|
|
|
|
/* 0x50 */ Matrix4f userTransformMtx; // provided for user code to apply an additional multiplicative transformation
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0x90 */ Vec3f center;
|
|
|
|
/* 0x9C */ u8 minChildModelIndex;
|
|
|
|
/* 0x9D */ u8 maxChildModelIndex;
|
|
|
|
/* 0x9E */ u8 renderMode;
|
2023-07-18 11:07:58 +02:00
|
|
|
/* 0x9F */ u8 matrixFreshness;
|
2021-09-22 13:17:46 +02:00
|
|
|
} ModelTransformGroup; // size = 0xA0
|
|
|
|
|
|
|
|
typedef Model* ModelList[MAX_MODELS];
|
|
|
|
typedef ModelTransformGroup* ModelTransformGroupList[MAX_MODEL_TRANSFORM_GROUPS];
|
|
|
|
|
2022-10-01 03:44:48 +02:00
|
|
|
typedef struct ModelIDList {
|
|
|
|
u16 count;
|
2023-02-14 14:14:14 +01:00
|
|
|
u16 list[VLA];
|
2022-10-01 03:44:48 +02:00
|
|
|
} ModelIDList;
|
|
|
|
|
2021-09-22 13:17:46 +02:00
|
|
|
typedef struct ModelLocalVertexCopy {
|
|
|
|
/* 0x00 */ s32 numVertices;
|
|
|
|
/* 0x04 */ Vtx* minVertexAddr;
|
|
|
|
/* 0x08 */ Gfx* gfxCopy[2];
|
|
|
|
/* 0x10 */ Vtx* vtxCopy[2];
|
|
|
|
/* 0x18 */ s32 selector;
|
|
|
|
} ModelLocalVertexCopy; // size = 0x1C
|
|
|
|
|
2022-12-12 13:31:29 +01:00
|
|
|
typedef ModelLocalVertexCopy* ModelLocalVertexCopyList[16];
|
2022-06-17 11:21:13 +02:00
|
|
|
|
2021-09-22 13:17:46 +02:00
|
|
|
typedef struct ModelTreeInfo {
|
|
|
|
/* 0x00 */ u8 modelIndex;
|
2021-12-13 10:27:28 +01:00
|
|
|
/* 0x01 */ u8 treeDepth;
|
2023-01-13 08:56:28 +01:00
|
|
|
/* 0x02 */ u8 textureID;
|
2021-09-22 13:17:46 +02:00
|
|
|
/* 0x03 */ char unk_03;
|
|
|
|
} ModelTreeInfo; // size = 0x04
|
|
|
|
|
|
|
|
typedef struct TextureHandle {
|
|
|
|
/* 0x00 */ Gfx* gfx;
|
2022-08-06 14:14:04 +02:00
|
|
|
/* 0x04 */ TextureHeader header;
|
2022-08-07 14:42:54 +02:00
|
|
|
/* 0x34 */ IMG_PTR raster;
|
|
|
|
/* 0x38 */ PAL_PTR palette;
|
|
|
|
/* 0x3C */ IMG_PTR auxRaster;
|
|
|
|
/* 0x40 */ PAL_PTR auxPalette;
|
2021-09-22 13:17:46 +02:00
|
|
|
} TextureHandle; // size = 0x44
|
|
|
|
|
|
|
|
typedef struct ModelBlueprint {
|
|
|
|
/* 0x0 */ s16 flags;
|
|
|
|
/* 0x2 */ char unk_02[0x2];
|
|
|
|
/* 0x4 */ ModelNode* mdlNode;
|
|
|
|
/* 0x8 */ ModelGroupData* groupData;
|
2022-09-08 14:21:07 +02:00
|
|
|
/* 0xC */ Mtx* mtx;
|
2021-09-22 13:17:46 +02:00
|
|
|
} ModelBlueprint; // size = 0x10
|
|
|
|
|
2021-10-03 17:44:16 +02:00
|
|
|
typedef void(*ModelCustomGfxBuilderFunc)(s32 index);
|
|
|
|
|
|
|
|
typedef Gfx* ModelCustomGfxList[32];
|
|
|
|
typedef ModelCustomGfxBuilderFunc ModelCustomGfxBuilderList[32];
|
2021-09-22 13:17:46 +02:00
|
|
|
|
|
|
|
typedef enum ModelPropertyKeys {
|
2023-07-18 11:07:58 +02:00
|
|
|
MODEL_PROP_KEY_RENDER_MODE = 0x5C,
|
|
|
|
MODEL_PROP_KEY_CAMERA_DATA = 0x5D,
|
|
|
|
MODEL_PROP_KEY_TEXTURE_NAME = 0x5E,
|
|
|
|
MODEL_PROP_KEY_SPECIAL = 0x5F,
|
|
|
|
MODEL_PROP_KEY_GROUP_INFO = 0x60,
|
|
|
|
MODEL_PROP_KEY_BOUNDING_BOX = 0x61,
|
|
|
|
MODEL_PROP_KEY_62 = 0x62,
|
2021-09-22 13:17:46 +02:00
|
|
|
} ModelPropertyKeys;
|
|
|
|
|
|
|
|
typedef enum ShapeTypes {
|
2023-07-18 11:07:58 +02:00
|
|
|
SHAPE_TYPE_MODEL = 2,
|
|
|
|
SHAPE_TYPE_GROUP = 5,
|
|
|
|
SHAPE_TYPE_ROOT = 7,
|
|
|
|
SHAPE_TYPE_SPECIAL_GROUP = 10,
|
2021-09-22 13:17:46 +02:00
|
|
|
} ShapeTypes;
|
|
|
|
|
2023-07-18 11:07:58 +02:00
|
|
|
typedef enum GroupTypes {
|
|
|
|
GROUP_TYPE_0 = 0,
|
|
|
|
GROUP_TYPE_1 = 1,
|
|
|
|
} GroupTypes;
|
|
|
|
|
2023-01-13 08:56:28 +01:00
|
|
|
typedef enum ExtraTileTypes {
|
2023-11-24 05:06:58 +01:00
|
|
|
EXTRA_TILE_NONE = 0, // texture contains only a single tile
|
|
|
|
EXTRA_TILE_MIPMAPS = 1, // texture contais mipmaps
|
|
|
|
EXTRA_TILE_AUX_SAME_AS_MAIN = 2, // texture contains main and aux images with identical fmt and size
|
|
|
|
EXTRA_TILE_AUX_INDEPENDENT = 3, // texture contains main and aux images with independent fmt and size
|
|
|
|
EXTRA_TILE_4 = 4, // only use-case may be a mistake? unused and mostly unimplemented
|
2023-01-13 08:56:28 +01:00
|
|
|
} ExtraTileTypes;
|
|
|
|
|
2023-02-14 14:14:14 +01:00
|
|
|
#define SHAPE_SIZE_LIMIT 0x8000
|
|
|
|
|
2023-02-25 09:30:02 +01:00
|
|
|
typedef struct ShapeFileHeader {
|
2022-10-17 09:46:24 +02:00
|
|
|
/* 0x00 */ ModelNode* root;
|
|
|
|
/* 0x04 */ Vtx_t* vertexTable;
|
|
|
|
/* 0x08 */ char** modelNames;
|
|
|
|
/* 0x0C */ char** colliderNames;
|
|
|
|
/* 0x10 */ char** zoneNames;
|
|
|
|
/* 0x14 */ unsigned char pad_14[0xC];
|
2023-02-25 09:30:02 +01:00
|
|
|
} ShapeFileHeader; // size = 0x20
|
|
|
|
|
|
|
|
typedef struct ShapeFile {
|
|
|
|
/* 0x00 */ ShapeFileHeader header;
|
2023-11-24 05:06:58 +01:00
|
|
|
/* 0x20 */ u8 data[SHAPE_SIZE_LIMIT - sizeof(ShapeFileHeader)];
|
2022-10-17 09:46:24 +02:00
|
|
|
} ShapeFile; // size = variable
|
|
|
|
|
2021-09-22 13:17:46 +02:00
|
|
|
typedef ModelTreeInfo ModelTreeInfoList[0x200];
|
2023-11-10 06:19:40 +01:00
|
|
|
extern ModelTreeInfoList* gCurrentModelTreeNodeInfo;
|
2022-05-27 15:03:19 +02:00
|
|
|
extern ModelList* gCurrentModels;
|
2021-09-22 13:17:46 +02:00
|
|
|
|
2023-11-24 05:06:58 +01:00
|
|
|
void mdl_set_depth_tint_params(u8 primR, u8 primG, u8 primB, u8 primA, u8 fogR, u8 fogG, u8 fogB, s32 fogStart, s32 fogEnd);
|
|
|
|
void mdl_set_remap_tint_params(u8 primR, u8 primG, u8 primB, u8 envR, u8 envG, u8 envB);
|
|
|
|
void mdl_get_remap_tint_params(u8* primR, u8* primG, u8* primB, u8* envR, u8* envG, u8* envB);
|
2022-10-25 12:04:54 +02:00
|
|
|
|
2022-10-16 16:22:18 +02:00
|
|
|
void init_model_data(void);
|
2021-12-20 16:59:25 +01:00
|
|
|
void update_model_animator(s32);
|
2021-10-29 19:57:15 +02:00
|
|
|
void update_model_animator_with_transform(s32 animatorID, Mtx* mtx);
|
2021-12-20 16:59:25 +01:00
|
|
|
void set_mdl_custom_gfx_set(Model*, s32, u32);
|
2023-01-13 08:56:28 +01:00
|
|
|
ModelNodeProperty* get_model_property(ModelNode* node, ModelPropertyKeys key);
|
2023-06-29 14:06:23 +02:00
|
|
|
void load_texture_variants(u32 romOffset, s32 textureID, s32 baseOffset, s32 size);
|
2021-10-29 19:57:15 +02:00
|
|
|
s32 step_model_animator(ModelAnimator* animator);
|
2022-05-05 16:08:16 +02:00
|
|
|
AnimatorNode* get_animator_node_for_tree_index(ModelAnimator* animator, s32 treeIndex);
|
|
|
|
AnimatorNode* get_animator_node_with_id(ModelAnimator* animator, s32 id);
|
2021-10-29 19:57:15 +02:00
|
|
|
void animator_update_model_transforms(ModelAnimator* animator, Mtx* rootTransform);
|
|
|
|
void render_animated_model(s32 animatorID, Mtx* rootTransform);
|
|
|
|
void animator_node_update_model_transform(ModelAnimator* animator, f32 (*flipMtx)[4], AnimatorNode* node,
|
|
|
|
Mtx* rootTransform);
|
2022-11-22 05:12:28 +01:00
|
|
|
void init_worker_list(void);
|
2022-10-16 16:22:18 +02:00
|
|
|
ModelAnimator* get_animator_by_index(s32 animModelID);
|
|
|
|
void reset_animator_list(void);
|
2022-03-20 11:12:30 +01:00
|
|
|
void delete_model_animator_node(AnimatorNode* node);
|
|
|
|
void delete_model_animator_nodes(ModelAnimator* animator);
|
|
|
|
void delete_model_animator(ModelAnimator* animator);
|
2022-07-17 18:38:19 +02:00
|
|
|
void render_animated_model_with_vertices(s32 animatorID, Mtx* rootTransform, s32 segment, void* baseAddr);
|
2021-10-29 19:57:15 +02:00
|
|
|
void appendGfx_animator(ModelAnimator* animator);
|
2022-12-07 09:39:22 +01:00
|
|
|
ModelAnimator* set_animator_render_callback(s32 animModelID, void* callbackArg, void (*callbackFunc)(void*));
|
2021-10-29 19:57:15 +02:00
|
|
|
void reload_mesh_animator_tree(ModelAnimator* animator);
|
|
|
|
s32 step_mesh_animator(ModelAnimator* animator);
|
2022-10-16 16:22:18 +02:00
|
|
|
|
|
|
|
void set_custom_gfx_builders(s32 customGfxIndex, ModelCustomGfxBuilderFunc pre, ModelCustomGfxBuilderFunc post);
|
|
|
|
void mdl_make_local_vertex_copy(s32 arg0, u16 treeIdx, s32);
|
2022-12-07 09:39:22 +01:00
|
|
|
void play_model_animation_starting_from(s32 index, s16* animPos, s32 framesToSkip);
|
2022-10-16 16:22:18 +02:00
|
|
|
|
2023-11-24 05:06:58 +01:00
|
|
|
void mdl_set_shroud_tint_params(u8 r, u8 g, u8 b, u8 a);
|
2022-11-11 20:34:36 +01:00
|
|
|
|
2021-09-22 13:17:46 +02:00
|
|
|
#endif
|