// SPDX-License-Identifier: MIT // // Copyright (c) 2008-2022 Antonio Niño Díaz // // This file is part of Nitro Engine #ifndef NE_MODEL_H__ #define NE_MODEL_H__ /// @file NEModel.h /// @brief Functions to draw and handle models. /// @defgroup model_system Model handling system /// /// Functions to create and manipulate animated or static models. /// /// @{ #define NE_NO_TEXTURE -1 ///< Value that represents not having a texture #define NE_NO_MESH -1 ///< Value that represents not having a mesh #define NE_DEFAULT_MODELS 512 ///< Default max number of models /// Possible animation types. typedef enum { NE_ANIM_LOOP, ///< When the end is reached it jumps to the start. NE_ANIM_ONESHOT, ///< When the end is reached it stops. } NE_AnimationType; /// Holds information of the animation of a model. typedef struct { NE_Animation *animation; ///< Pointer to animation file NE_AnimationType type; ///< Animation type. int32_t speed; ///< Animation speed (f32). int32_t currframe; ///< Current frame. It can be between frames (f32). int32_t numframes; ///< Number of frames in the animation (int). } NE_AnimInfo; /// Possible model types. typedef enum { NE_Static, ///< Not animated. NE_Animated ///< Animated. } NE_ModelType; /// Holds information of a model. typedef struct { NE_ModelType modeltype; ///< Model type (static or animated) int meshindex; ///< Index of mesh (static or DSM) NE_AnimInfo *animinfo[2]; ///< Animation information (two can be blended) int32_t anim_blend; ///< Animation blend factor NE_Material *texture; ///< Material used by this model int x; ///< X position of the model (f32) int y; ///< Y position of the model (f32) int z; ///< Z position of the model (f32) int rx; ///< Rotation of the model by X axis int ry; ///< Rotation of the model by Y axis int rz; ///< Rotation of the model by Z axis int sx; ///< X scale of the model (f32) int sy; ///< Y scale of the model (f32) int sz; ///< Z scale of the model (f32) m4x3 *mat; ///< Transformation matrix assigned by the user. } NE_Model; /// Creates a new model object. /// /// @param type Model type (static or animated). /// @return Pointer to the newly created camera. NE_Model *NE_ModelCreate(NE_ModelType type); /// Deletes a model. /// /// @param model Pointer to the model. void NE_ModelDelete(NE_Model *model); /// Marks the mesh of a model to be freed when the model is deleted. /// /// When a model is loaded with NE_ModelLoadStaticMeshFAT() or /// NE_ModelLoadDSMFAT(), the mesh is read from storage into RAM to a buffer /// allocated witn malloc(). This buffer is freed with free() when /// NE_ModelDelete() is called. /// /// If the mesh is loaded using NE_ModelLoadStaticMesh() or NE_ModelLoadDSM(), /// Nitro Engine can't tell if the user has loaded it from storage, or if it has /// been included in the NDS file as data. If the user has loaded the mesh into /// a buffer allocated with malloc(), the user is responsible for calling free() /// after NE_ModelDelete(). /// /// NE_ModelFreeMeshWhenDeleted() gives you the option of skipping that last /// free(). After you call this function, NE_ModelDelete() will call free() for /// you automatically so that you don't have to keep track of the pointer in the /// logic of your program. /// /// @param model Pointer to the model. void NE_ModelFreeMeshWhenDeleted(NE_Model *model); /// Assign a display list in RAM to a static model. /// /// @param model Pointer to the model. /// @param pointer Pointer to the display list. /// @return It returns 1 on success, 0 on error. int NE_ModelLoadStaticMesh(NE_Model *model, const void *pointer); /// Loads a display list from a filesystem and assigns it to a static model. /// /// @param model Pointer to the model. /// @param path Path to the display list. /// @return It returns 1 on success, 0 on error. int NE_ModelLoadStaticMeshFAT(NE_Model *model, const char *path); /// Assign a material to a model. /// /// @param model Pointer to the model. /// @param material Pointer to the material. void NE_ModelSetMaterial(NE_Model *model, NE_Material *material); /// Assign an animation to a model. /// /// @param model Pointer to the model. /// @param anim Pointer to the animation. void NE_ModelSetAnimation(NE_Model *model, NE_Animation *anim); /// Assign a secondary animation to a model. /// /// The secondary animation is an animation that is averaged with the main /// animation. This is useful to do transitions between animations. This takes a /// bit more of CPU to display, though. /// /// Whenever you want to go back to having one animation, you have to use /// NE_ModelAnimSecondaryClear(). This function lets you stop blending /// animations, and it gives you the option to preserve the main or the /// secondary animation. /// /// Function NE_ModelAnimSecondarySetFactor() lets you specify a value to /// specify the blending factor, where 0.0 means "display the main animation /// only" and 1.0 means "display the secondary animation only". The initial /// value after calling NE_ModelAnimSecondaryStart() is 0.0. /// /// @param model Pointer to the model. /// @param anim Pointer to the animation. void NE_ModelSetAnimationSecondary(NE_Model *model, NE_Animation *anim); /// Draw a model. /// /// @param model Pointer to the model. void NE_ModelDraw(const NE_Model *model); /// Clone model. /// /// This clones the mesh, including the animation, the material it uses. It /// doesn't actually duplicate the memory used in RAM to store the mesh, and it /// keeps track of how many models use the same mesh. NE_ModelDelete() only /// frees the mesh when the user deletes the last model that uses it. /// /// @param dest Pointer to the destination model. /// @param source Pointer to the source model. void NE_ModelClone(NE_Model *dest, NE_Model *source); /// Set position of a model. /// /// @param model Pointer to the model. /// @param x (x, y, z) Coordinates (f32). /// @param y (x, y, z) Coordinates (f32). /// @param z (x, y, z) Coordinates (f32). void NE_ModelSetCoordI(NE_Model *model, int x, int y, int z); /// Set position of a model. /// /// @param m Pointer to the model. /// @param x (x, y, z) Coordinates (float). /// @param y (x, y, z) Coordinates (float). /// @param z (x, y, z) Coordinates (float). #define NE_ModelSetCoord(m, x, y, z) \ NE_ModelSetCoordI(m, floattof32(x), floattof32(y), floattof32(z)) /// Set scale of a model. /// /// @param model Pointer to the model. /// @param x (x, y, z) Scale (f32). /// @param y (x, y, z) Scale (f32). /// @param z (x, y, z) Scale (f32). void NE_ModelScaleI(NE_Model *model, int x, int y, int z); /// Set scale of a model. /// /// @param m Pointer to the model. /// @param x (x, y, z) Scale (float). /// @param y (x, y, z) Scale (float). /// @param z (x, y, z) Scale (float). #define NE_ModelScale(m, x, y, z) \ NE_ModelScaleI(m, floattof32(x), floattof32(y), floattof32(z)) /// Translate a model. /// /// @param model Pointer to the model. /// @param x (x, y, z) Translate vector (f32). /// @param y (x, y, z) Translate vector (f32). /// @param z (x, y, z) Translate vector (f32). void NE_ModelTranslateI(NE_Model *model, int x, int y, int z); /// Translate a model. /// /// @param m Pointer to the model. /// @param x (x, y, z) Translate vector (float). /// @param y (x, y, z) Translate vector (float). /// @param z (x, y, z) Translate vector (float). #define NE_ModelTranslate(m, x, y, z) \ NE_ModelTranslateI(m, floattof32(x), floattof32(y), floattof32(z)) /// Set rotation of a model. /// /// This function sets the rotation of the model to the provided values. /// /// @param model Pointer to the model. /// @param rx Rotation by X axis (0 - 511). /// @param ry Rotation by Y axis (0 - 511). /// @param rz Rotation by Z axis (0 - 511). void NE_ModelSetRot(NE_Model *model, int rx, int ry, int rz); /// Rotate a model. /// /// This function adds the values to the current rotation of the model. /// /// @param model Pointer to the model. /// @param rx Rotation by X axis (0 - 511). /// @param ry Rotation by Y axis (0 - 511). /// @param rz Rotation by Z axis (0 - 511). void NE_ModelRotate(NE_Model *model, int rx, int ry, int rz); /// Assigns a 4x3 transformation matrix to a model. /// /// When a matrix is assigned, the scale, position and rotation of the model /// will be ignored. /// /// Note that the provided matrix is copied to the internal state of the model, /// so the caller of the function doesn't need to keep it in memory. /// /// @param model Pointer to the model. /// @param mat Matrix to be used. /// @return Returns 1 on success, 0 on failure. int NE_ModelSetMatrix(NE_Model *model, m4x3 *mat); /// Clears the 4x3 transformation matrix of a model. /// /// The model will start using the individual scale, translation and rotation /// values. /// /// @param model Pointer to the model. void NE_ModelClearMatrix(NE_Model *model); /// Update internal state of the animation of all models. void NE_ModelAnimateAll(void); /// Starts the animation of an animated model. /// /// The speed can be positive or negative. A speed of 0 stops the animation, a /// speed of 1 << 12 means that the model will advance one model frame per NDS /// frame. Anything in between will advance less than one model frame per NDS /// frame. /// /// @param model Pointer to the model. /// @param type Animation type (NE_ANIM_LOOP / NE_ANIM_ONESHOT). /// @param speed Animation speed. (f32) void NE_ModelAnimStart(NE_Model *model, NE_AnimationType type, int32_t speed); /// Starts the secondary animation of an animated model. /// /// @param model Pointer to the model. /// @param type Animation type (NE_ANIM_LOOP / NE_ANIM_ONESHOT). /// @param speed Animation speed. (f32) void NE_ModelAnimSecondaryStart(NE_Model *model, NE_AnimationType type, int32_t speed); /// Sets animation speed. /// /// The speed can be positive or negative. A speed of 0 stops the animation, a /// speed of 1 << 12 means that the model will advance one model frame per NDS /// frame. Anything in between will advance less than one model frame per NDS /// frame. /// /// @param model Pointer to the model. /// @param speed New speed. (f32) void NE_ModelAnimSetSpeed(NE_Model *model, int32_t speed); /// Sets animation speed of the secondary animation. /// /// @param model Pointer to the model. /// @param speed New speed. (f32) void NE_ModelAnimSecondarySetSpeed(NE_Model *model, int32_t speed); /// Returns the current frame of an animated model. /// /// @param model Pointer to the model. /// @return Returns the frame in f32 format. int32_t NE_ModelAnimGetFrame(const NE_Model *model); /// Returns the current frame of the secondary animation of an animated model. /// /// @param model Pointer to the model. /// @return Returns the frame in f32 format. int32_t NE_ModelAnimSecondaryGetFrame(const NE_Model *model); /// Sets the current frame of an animated model. /// /// @param model Pointer to the model. /// @param frame Frame to set. (f32) void NE_ModelAnimSetFrame(NE_Model *model, int32_t frame); /// Sets the current frame of the secondary animation of an animated model. /// /// @param model Pointer to the model. /// @param frame Frame to set. (f32) void NE_ModelAnimSecondarySetFrame(NE_Model *model, int32_t frame); /// Sets the current blending factor between animations. /// /// This is a value between 0.0 and 1.0 where 0.0 means "display the main /// animation only" and 1.0 means "display the secondary animation only". /// /// @param model Pointer to the model. /// @param factor Blending factor to set. (f32) void NE_ModelAnimSecondarySetFactor(NE_Model *model, int32_t factor); /// Clears the secondary animation of a model. /// /// It is possible to replace the main animation by the secondary animation, or /// to simply remove the secondary animation. In both cases, the secondary /// animation will be cleared. /// /// @param model Pointer to the model. /// @param replace_base_anim Set to true to replace the base animation by the /// secondary animation. void NE_ModelAnimSecondaryClear(NE_Model *model, bool replace_base_anim); /// Loads a DSM file stored in RAM to a model. /// /// @param model Pointer to the model. /// @param pointer Pointer to the file. /// @return It returns 1 on success, 0 on error. int NE_ModelLoadDSM(NE_Model *model, const void *pointer); /// Loads a DSM file stored in a filesystem to a model. /// /// @param model Pointer to the model. /// @param path Path to the file. /// @return It returns 1 on success, 0 on error. int NE_ModelLoadDSMFAT(NE_Model *model, const char *path); /// Deletes all models and frees all memory used by them. void NE_ModelDeleteAll(void); /// Resets the model system and sets the maximun number of models. /// /// @param max_models Number of models. If it is lower than 1, it will create /// space for NE_DEFAULT_MODELS. /// @return Returns 0 on success. int NE_ModelSystemReset(int max_models); /// Ends model system and frees all memory used by it. void NE_ModelSystemEnd(void); /// @} #endif // NE_MODEL_H__