diff --git a/include/NEModel.h b/include/NEModel.h index 5647b4c..fb207e9 100644 --- a/include/NEModel.h +++ b/include/NEModel.h @@ -58,6 +58,7 @@ typedef struct { 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. @@ -225,6 +226,27 @@ void NE_ModelSetRot(NE_Model *model, int rx, int ry, int rz); /// @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); diff --git a/source/NEModel.c b/source/NEModel.c index 792c8b7..3b9a737 100644 --- a/source/NEModel.c +++ b/source/NEModel.c @@ -141,6 +141,8 @@ NE_Model *NE_ModelCreate(NE_ModelType type) model->sx = model->sy = model->sz = inttof32(1); + model->mat = NULL; + model->modeltype = type; model->meshindex = NE_NO_MESH; @@ -186,6 +188,9 @@ void NE_ModelDelete(NE_Model *model) free(model->animinfo[i]); } + if (model->mat != NULL) + free(model->mat); + // If there is an asigned mesh if (model->meshindex != NE_NO_MESH) ne_mesh_delete(model->meshindex); @@ -271,20 +276,27 @@ void NE_ModelDraw(const NE_Model *model) MATRIX_PUSH = 0; - MATRIX_TRANSLATE = model->x; - MATRIX_TRANSLATE = model->y; - MATRIX_TRANSLATE = model->z; + if (model->mat != NULL) + { + glMultMatrix4x3(model->mat); + } + else + { + MATRIX_TRANSLATE = model->x; + MATRIX_TRANSLATE = model->y; + MATRIX_TRANSLATE = model->z; - if (model->rx != 0) - glRotateXi(model->rx << 6); - if (model->ry != 0) - glRotateYi(model->ry << 6); - if (model->rz != 0) - glRotateZi(model->rz << 6); + if (model->rx != 0) + glRotateXi(model->rx << 6); + if (model->ry != 0) + glRotateYi(model->ry << 6); + if (model->rz != 0) + glRotateZi(model->rz << 6); - MATRIX_SCALE = model->sx; - MATRIX_SCALE = model->sy; - MATRIX_SCALE = model->sz; + MATRIX_SCALE = model->sx; + MATRIX_SCALE = model->sy; + MATRIX_SCALE = model->sz; + } if (NE_TestTouch) { @@ -404,6 +416,33 @@ void NE_ModelSetRot(NE_Model *model, int rx, int ry, int rz) model->rz = rz; } +int NE_ModelSetMatrix(NE_Model *model, m4x3 *mat) +{ + NE_AssertPointer(model, "NULL model pointer"); + NE_AssertPointer(mat, "NULL matrix pointer"); + + if (model->mat == NULL) + { + model->mat = malloc(sizeof(m4x3)); + if (model->mat == NULL) + return 0; + } + + memcpy(model->mat, mat, sizeof(m4x3)); + + return 1; +} + +void NE_ModelClearMatrix(NE_Model *model) +{ + NE_AssertPointer(model, "NULL pointer"); + + if (model->mat == NULL) + return; + + free(model->mat); +} + void NE_ModelAnimateAll(void) { if (!ne_model_system_inited)