diff options
| -rw-r--r-- | API.md | 68 | ||||
| -rw-r--r-- | ReiLua_API.lua | 66 | ||||
| -rw-r--r-- | changelog | 1 | ||||
| -rw-r--r-- | devnotes | 3 | ||||
| -rw-r--r-- | examples/iqm_test/main.lua | 17 | ||||
| -rw-r--r-- | include/models.h | 9 | ||||
| -rw-r--r-- | src/lua_core.c | 10 | ||||
| -rw-r--r-- | src/models.c | 240 |
8 files changed, 342 insertions, 72 deletions
@@ -6605,16 +6605,16 @@ Set model transform matrix > success = RL.SetModelMesh( Model model, int meshId, Mesh mesh ) -Get model mesh. Return as lightuserdata +Set model mesh. - Failure return false - Success return true --- -> success = RL.SetModelMaterial( Model model, int modelMaterialId, Material material ) +> success = RL.SetModelMaterial( Model model, int materialId, Material material ) -Copies material to model material +Set material to model material - Failure return false - Success return true @@ -7057,6 +7057,18 @@ Update model animation pose --- +> RL.UnloadModelAnimation( ModelAnimation animation ) + +Unload animation data + +--- + +> RL.UnloadModelAnimations( ModelAnimation{} animations ) + +Unload animation table data + +--- + > valid = RL.IsModelAnimationValid( Model model, ModelAnimation animation ) Check model animation skeleton match @@ -7065,6 +7077,30 @@ Check model animation skeleton match --- +> success = RL.SetModelAnimationBone( ModelAnimation animation, int boneId, BoneInfo bone ) + +Set modelAnimation bones information (skeleton) + +- Failure return false +- Success return true + +--- + +> success = RL.SetModelAnimationFramePose( ModelAnimation animation, int frame, int boneId, Transform pose ) + +Set modelAnimation bones base transformation (pose) + +- Failure return false +- Success return true + +--- + +> RL.SetModelAnimationName( ModelAnimation animation, string name ) + +Set modelAnimation name + +--- + > boneCount = RL.GetModelAnimationBoneCount( ModelAnimation animation ) Return modelAnimation bone count @@ -7081,6 +7117,32 @@ Return modelAnimation frame count --- +> bone = RL.GetModelAnimationBone( ModelAnimation animation, int boneId ) + +Get modelAnimation bones information (skeleton) + +- Failure return nil +- Success return BoneInfo + +--- + +> pose = RL.GetModelAnimationFramePose( ModelAnimation animation, int frame, int boneId ) + +Get modelAnimation bones base transformation (pose) + +- Failure return nil +- Success return Transform + +--- + +> name = RL.GetModelAnimationName( ModelAnimation animation ) + +Get modelAnimation name + +- Success return string + +--- + ## Model - Collision detection functions --- diff --git a/ReiLua_API.lua b/ReiLua_API.lua index 2c02e30..1e35277 100644 --- a/ReiLua_API.lua +++ b/ReiLua_API.lua @@ -4001,7 +4001,7 @@ function RL.GetModelBoundingBox( model ) end ---@return any RL.SetModelTransform function RL.SetModelTransform( model, transform ) end ----Get model mesh. Return as lightuserdata +---Set model mesh. ---- Failure return false ---- Success return true ---@param model any @@ -4010,14 +4010,14 @@ function RL.SetModelTransform( model, transform ) end ---@return any success function RL.SetModelMesh( model, meshId, mesh ) end ----Copies material to model material +---Set material to model material ---- Failure return false ---- Success return true ---@param model any ----@param modelMaterialId integer +---@param materialId integer ---@param material any ---@return any success -function RL.SetModelMaterial( model, modelMaterialId, material ) end +function RL.SetModelMaterial( model, materialId, material ) end ---Set material for a mesh (Mesh and material on this model) ---@param model any @@ -4436,6 +4436,16 @@ function RL.LoadModelAnimations( fileName ) end ---@return any RL.UpdateModelAnimation function RL.UpdateModelAnimation( model, animation, frame ) end +---Unload animation data +---@param animation any +---@return any RL.UnloadModelAnimation +function RL.UnloadModelAnimation( animation ) end + +---Unload animation table data +---@param animations table +---@return any RL.UnloadModelAnimations +function RL.UnloadModelAnimations( animations ) end + ---Check model animation skeleton match ---- Success return bool ---@param model any @@ -4443,6 +4453,31 @@ function RL.UpdateModelAnimation( model, animation, frame ) end ---@return any valid function RL.IsModelAnimationValid( model, animation ) end +---Set modelAnimation bones information (skeleton) +---- Failure return false +---- Success return true +---@param animation any +---@param boneId integer +---@param bone any +---@return any success +function RL.SetModelAnimationBone( animation, boneId, bone ) end + +---Set modelAnimation bones base transformation (pose) +---- Failure return false +---- Success return true +---@param animation any +---@param frame integer +---@param boneId integer +---@param pose any +---@return any success +function RL.SetModelAnimationFramePose( animation, frame, boneId, pose ) end + +---Set modelAnimation name +---@param animation any +---@param name string +---@return any RL.SetModelAnimationName +function RL.SetModelAnimationName( animation, name ) end + ---Return modelAnimation bone count ---- Success return int ---@param animation any @@ -4455,6 +4490,29 @@ function RL.GetModelAnimationBoneCount( animation ) end ---@return any frameCount function RL.GetModelAnimationFrameCount( animation ) end +---Get modelAnimation bones information (skeleton) +---- Failure return nil +---- Success return BoneInfo +---@param animation any +---@param boneId integer +---@return any bone +function RL.GetModelAnimationBone( animation, boneId ) end + +---Get modelAnimation bones base transformation (pose) +---- Failure return nil +---- Success return Transform +---@param animation any +---@param frame integer +---@param boneId integer +---@return any pose +function RL.GetModelAnimationFramePose( animation, frame, boneId ) end + +---Get modelAnimation name +---- Success return string +---@param animation any +---@return any name +function RL.GetModelAnimationName( animation ) end + -- Model - Collision detection functions ---Check collision between two spheres @@ -21,6 +21,7 @@ KEY CHANGES: - ADDED: Raygui wrapper library disabled and styles for each element. - ADDED: Files management functions. - ADDED: More Model management functions. + - ADDED: More Model animations management functions. DETAILED CHANGES: - REMOVED: DrawLineBezierQuad, DrawLineBezierCubic. @@ -19,7 +19,7 @@ Backlog { * Core * Automation events functionality. * Models - * More Animation management functions. + * Mesh bone weight management? * Examples * Improve Dungeon crawler example by generating custom mesh instead of drawing 3D quads. @@ -38,5 +38,4 @@ Needs Testing { * rlUpdateTexture * rlReadTexturePixels * rlReadScreenPixels - * SetModelMesh Test unloading for double free or other errors. } diff --git a/examples/iqm_test/main.lua b/examples/iqm_test/main.lua index ef1549c..f5c0d49 100644 --- a/examples/iqm_test/main.lua +++ b/examples/iqm_test/main.lua @@ -24,6 +24,10 @@ function RL.init() RL.SetCamera3DTarget( camera, { 0, 0, 0 } ) RL.SetCamera3DUp( camera, { 0, 1, 0 } ) + RL.SetTextLineSpacing( 26 ) + -- If custom material or mesh is set to model, we need to use custom unloading to prevent double free errors. + RL.SetGCUnload( false ) + texture = RL.LoadTexture( RL.GetBasePath().."../resources/images/monkey_tex.png" ) material = RL.CreateMaterial( { @@ -37,8 +41,10 @@ function RL.init() }, }, } ) - model = RL.LoadModel( RL.GetBasePath().."../resources/iqm/monkey.iqm" ) + -- Unload old material. + RL.UnloadMaterial( RL.GetModelMaterial( model, 0 ) ) + RL.SetModelMaterial( model, 0, material ) animations = RL.LoadModelAnimations( RL.GetBasePath().."../resources/iqm/monkey.iqm" ) end @@ -85,5 +91,12 @@ function RL.draw() Space: Play animation\ Up arrow: Inreace animation speed\ Down arrow: Decreace animation speed", - { 10, 10 }, 30, RL.WHITE ) + { 10, 10 }, 30, RL.WHITE + ) +end + +function RL.exit() + RL.UnloadTexture( texture ) + RL.UnloadModel( model ) + RL.UnloadModelAnimations( animations ) end diff --git a/include/models.h b/include/models.h index 33fb291..68ebb3e 100644 --- a/include/models.h +++ b/include/models.h @@ -3,7 +3,6 @@ /* Internals. */ void unloadMaterial( Material *material ); /* Deleted from raylib. Need for freeing models. */ -void UnloadModelKeepMeshes( Model model ); void DrawBillboardProNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ); void DrawBillboardRecNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint ); @@ -97,9 +96,17 @@ int lmodelsGetMaterialParams( lua_State *L ); /* Model animations management functions. */ int lmodelsLoadModelAnimations( lua_State *L ); int lmodelsUpdateModelAnimation( lua_State *L ); +int lmodelsUnloadModelAnimation( lua_State *L ); +int lmodelsUnloadModelAnimations( lua_State *L ); int lmodelsIsModelAnimationValid( lua_State *L ); +int lmodelsSetModelAnimationBone( lua_State *L ); +int lmodelsSetModelAnimationFramePose( lua_State *L ); +int lmodelsSetModelAnimationName( lua_State *L ); int lmodelsGetModelAnimationBoneCount( lua_State *L ); int lmodelsGetModelAnimationFrameCount( lua_State *L ); +int lmodelsGetModelAnimationBone( lua_State *L ); +int lmodelsGetModelAnimationFramePose( lua_State *L ); +int lmodelsGetModelAnimationName( lua_State *L ); /* Collision detection functions. */ int lmodelsCheckCollisionSpheres( lua_State *L ); int lmodelsCheckCollisionBoxes( lua_State *L ); diff --git a/src/lua_core.c b/src/lua_core.c index 3bfce93..6195c9f 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -77,7 +77,6 @@ static void defineTexture() { luaL_newmetatable( L, "Texture" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); - lua_pushcfunction( L, gcTexture ); lua_setfield( L, -2, "__gc" ); } @@ -267,7 +266,6 @@ static int gcModel( lua_State *L ) { if ( state->gcUnload ) { Model *model = luaL_checkudata( L, 1, "Model" ); UnloadModel( *model ); - // UnloadModelKeepMeshes( *model ); } return 0; } @@ -1649,9 +1647,17 @@ void luaRegister() { /* Model animations management functions. */ assingGlobalFunction( "LoadModelAnimations", lmodelsLoadModelAnimations ); assingGlobalFunction( "UpdateModelAnimation", lmodelsUpdateModelAnimation ); + assingGlobalFunction( "UnloadModelAnimation", lmodelsUnloadModelAnimation ); + assingGlobalFunction( "UnloadModelAnimations", lmodelsUnloadModelAnimations ); assingGlobalFunction( "IsModelAnimationValid", lmodelsIsModelAnimationValid ); + assingGlobalFunction( "SetModelAnimationBone", lmodelsSetModelAnimationBone ); + assingGlobalFunction( "SetModelAnimationFramePose", lmodelsSetModelAnimationFramePose ); + assingGlobalFunction( "SetModelAnimationName", lmodelsSetModelAnimationName ); assingGlobalFunction( "GetModelAnimationBoneCount", lmodelsGetModelAnimationBoneCount ); assingGlobalFunction( "GetModelAnimationFrameCount", lmodelsGetModelAnimationFrameCount ); + assingGlobalFunction( "GetModelAnimationBone", lmodelsGetModelAnimationBone ); + assingGlobalFunction( "GetModelAnimationFramePose", lmodelsGetModelAnimationFramePose ); + assingGlobalFunction( "GetModelAnimationName", lmodelsGetModelAnimationName ); /* Collision detection functions. */ assingGlobalFunction( "CheckCollisionSpheres", lmodelsCheckCollisionSpheres ); assingGlobalFunction( "CheckCollisionBoxes", lmodelsCheckCollisionBoxes ); diff --git a/src/models.c b/src/models.c index 7efee95..490ac13 100644 --- a/src/models.c +++ b/src/models.c @@ -10,26 +10,6 @@ void unloadMaterial( Material *material ) { free( material->maps ); } -// Unload model (but not meshes) from memory (RAM and/or VRAM) -void UnloadModelKeepMeshes( Model model ) { - // Unload materials maps - // NOTE: As the user could be sharing shaders and textures between models, - // we don't unload the material but just free it's maps, - // the user is responsible for freeing models shaders and textures - for (int i = 0; i < model.materialCount; i++) RL_FREE(model.materials[i].maps); - - // Unload arrays - RL_FREE(model.meshes); - RL_FREE(model.materials); - RL_FREE(model.meshMaterial); - - // Unload animation data - RL_FREE(model.bones); - RL_FREE(model.bindPose); - - TraceLog( LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM" ); -} - void DrawBillboardProNoRatio( Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) { // NOTE: Billboard size will maintain source rectangle aspect ratio, size will represent billboard width // Vector2 sizeRatio = { size.x*(float)source.width/source.height, size.y }; @@ -589,7 +569,7 @@ int lmodelsSetModelTransform( lua_State *L ) { /* > success = RL.SetModelMesh( Model model, int meshId, Mesh mesh ) -Get model mesh. Return as lightuserdata +Set model mesh. - Failure return false - Success return true @@ -600,52 +580,35 @@ int lmodelsSetModelMesh( lua_State *L ) { Mesh *mesh = uluaGetMesh( L, 3 ); if ( 0 <= meshId && meshId < model->meshCount ) { - // TODO Test if mesh should be copied instead. Is there issues with unloading. model->meshes[ meshId ] = *mesh; lua_pushboolean( L, true ); } else { - TraceLog( LOG_WARNING, "MeshId %d out of bounds", meshId ); + TraceLog( LOG_WARNING, "SetModelMesh meshId %d out of bounds", meshId ); lua_pushboolean( L, false ); } return 1; } /* -> success = RL.SetModelMaterial( Model model, int modelMaterialId, Material material ) +> success = RL.SetModelMaterial( Model model, int materialId, Material material ) -Copies material to model material +Set material to model material - Failure return false - Success return true */ int lmodelsSetModelMaterial( lua_State *L ) { Model *model = uluaGetModel( L, 1 ); - int modelMaterialId = luaL_checkinteger( L, 2 ); + int materialId = luaL_checkinteger( L, 2 ); Material *material = uluaGetMaterial( L, 3 ); - if ( 0 <= modelMaterialId && modelMaterialId < model->materialCount ) { - /* Copy material data instead of using pointer. Pointer would result in double free error. */ - model->materials[ modelMaterialId ].shader = material->shader; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_ALBEDO ] = material->maps[ MATERIAL_MAP_ALBEDO ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_METALNESS ] = material->maps[ MATERIAL_MAP_METALNESS ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_NORMAL ] = material->maps[ MATERIAL_MAP_NORMAL ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_ROUGHNESS ] = material->maps[ MATERIAL_MAP_ROUGHNESS ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_OCCLUSION ] = material->maps[ MATERIAL_MAP_OCCLUSION ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_EMISSION ] = material->maps[ MATERIAL_MAP_EMISSION ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_HEIGHT ] = material->maps[ MATERIAL_MAP_HEIGHT ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_CUBEMAP ] = material->maps[ MATERIAL_MAP_CUBEMAP ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_IRRADIANCE ] = material->maps[ MATERIAL_MAP_IRRADIANCE ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_PREFILTER ] = material->maps[ MATERIAL_MAP_PREFILTER ]; - model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_BRDF ] = material->maps[ MATERIAL_MAP_BRDF ]; - - for ( int i = 0; i < 4; i++ ) { - model->materials[ modelMaterialId ].params[i] = material->params[i]; - } + if ( 0 <= materialId && materialId < model->materialCount ) { + model->materials[ materialId ] = *material; lua_pushboolean( L, true ); } else { - TraceLog( LOG_WARNING, "SetModelMaterial modelMaterialId %d out of bounds", modelMaterialId ); + TraceLog( LOG_WARNING, "SetModelMaterial materialId %d out of bounds", materialId ); lua_pushboolean( L, false ); } return 1; @@ -661,8 +624,14 @@ int lmodelsSetModelMeshMaterial( lua_State *L ) { int meshId = luaL_checkinteger( L, 2 ); int materialId = luaL_checkinteger( L, 3 ); - SetModelMeshMaterial( model, meshId, materialId ); - + if ( 0 <= meshId && meshId < model->meshCount && 0 <= materialId && materialId < model->materialCount ) { + SetModelMeshMaterial( model, meshId, materialId ); + lua_pushboolean( L, true ); + } + else { + TraceLog( LOG_WARNING, "SetModelMaterial meshId %d or materialId %d out of bounds", meshId, materialId ); + lua_pushboolean( L, false ); + } return 0; } @@ -684,7 +653,7 @@ int lmodelsSetModelBone( lua_State *L ) { lua_pushboolean( L, true ); } else { - TraceLog( LOG_WARNING, "boneId %d out of bounds", boneId ); + TraceLog( LOG_WARNING, "SetModelBone boneId %d out of bounds", boneId ); lua_pushboolean( L, false ); } return 1; @@ -708,7 +677,7 @@ int lmodelsSetModelBindPose( lua_State *L ) { lua_pushboolean( L, true ); } else { - TraceLog( LOG_WARNING, "boneId %d out of bounds", boneId ); + TraceLog( LOG_WARNING, "SetModelBindPose boneId %d out of bounds", boneId ); lua_pushboolean( L, false ); } return 1; @@ -775,7 +744,7 @@ int lmodelsGetModelMesh( lua_State *L ) { lua_pushlightuserdata( L, &model->meshes[ meshId ] ); } else { - TraceLog( LOG_WARNING, "MeshId %d out of bounds", meshId ); + TraceLog( LOG_WARNING, "GetModelMesh meshId %d out of bounds", meshId ); lua_pushnil( L ); } return 1; @@ -797,7 +766,7 @@ int lmodelsGetModelMaterial( lua_State *L ) { lua_pushlightuserdata( L, &model->materials[ materialId ] ); } else { - TraceLog( LOG_WARNING, "MaterialId %d out of bounds", materialId ); + TraceLog( LOG_WARNING, "GetModelMaterial materialId %d out of bounds", materialId ); lua_pushnil( L ); } return 1; @@ -834,7 +803,7 @@ int lmodelsGetModelBone( lua_State *L ) { uluaPushBoneInfo( L, model->bones[ boneId ] ); } else { - TraceLog( LOG_WARNING, "BoneId %d out of bounds", boneId ); + TraceLog( LOG_WARNING, "GetModelBone boneId %d out of bounds", boneId ); lua_pushnil( L ); } return 1; @@ -856,7 +825,7 @@ int lmodelsGetModelBindPose( lua_State *L ) { uluaPushTransform( L, model->bindPose[ boneId ] ); } else { - TraceLog( LOG_WARNING, "BoneId %d out of bounds", boneId ); + TraceLog( LOG_WARNING, "GetModelBindPose boneId %d out of bounds", boneId ); lua_pushnil( L ); } return 1; @@ -1955,7 +1924,6 @@ int lmodelsLoadModelAnimations( lua_State *L ) { uluaPushModelAnimation( L, anims[i] ); lua_rawseti( L, -2, i+1 ); } - return 1; } TraceLog( state->logLevelInvalid, "Invalid file '%s'", lua_tostring( L, 1 ) ); @@ -1971,11 +1939,44 @@ Update model animation pose */ int lmodelsUpdateModelAnimation( lua_State *L ) { Model *model = uluaGetModel( L, 1 ); - ModelAnimation *modelAnimation = uluaGetModelAnimation( L, 2 ); + ModelAnimation *animation = uluaGetModelAnimation( L, 2 ); int frame = luaL_checkinteger( L, 3 ); - UpdateModelAnimation( *model, *modelAnimation, frame ); + UpdateModelAnimation( *model, *animation, frame ); + + return 0; +} + +/* +> RL.UnloadModelAnimation( ModelAnimation animation ) + +Unload animation data +*/ +int lmodelsUnloadModelAnimation( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + + UnloadModelAnimation( *animation ); + + return 0; +} + +/* +> RL.UnloadModelAnimations( ModelAnimation{} animations ) + +Unload animation table data +*/ +int lmodelsUnloadModelAnimations( lua_State *L ) { + int t = 1, i = 0; + lua_pushnil( L ); + while ( lua_next( L, t ) != 0 ) { + if ( lua_isuserdata( L, -1 ) ) { + ModelAnimation *animation = uluaGetModelAnimation( L, lua_gettop( L ) ); + UnloadModelAnimation( *animation ); + } + i++; + lua_pop( L, 1 ); + } return 0; } @@ -1988,9 +1989,72 @@ Check model animation skeleton match */ int lmodelsIsModelAnimationValid( lua_State *L ) { Model *model = uluaGetModel( L, 1 ); - ModelAnimation *modelAnimation = uluaGetModelAnimation( L, 2 ); + ModelAnimation *animation = uluaGetModelAnimation( L, 2 ); - lua_pushboolean( L, IsModelAnimationValid( *model, *modelAnimation ) ); + lua_pushboolean( L, IsModelAnimationValid( *model, *animation ) ); + + return 1; +} + +/* +> success = RL.SetModelAnimationBone( ModelAnimation animation, int boneId, BoneInfo bone ) + +Set modelAnimation bones information (skeleton) + +- Failure return false +- Success return true +*/ +int lmodelsSetModelAnimationBone( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + int boneId = luaL_checkinteger( L, 2 ); + BoneInfo bone = uluaGetBoneInfo( L, 3 ); + + if ( 0 <= boneId && boneId < animation->boneCount ) { + animation->bones[ boneId ] = bone; + lua_pushboolean( L, true ); + } + else { + TraceLog( LOG_WARNING, "SetModelAnimationBone boneId %d out of bounds", boneId ); + lua_pushboolean( L, false ); + } + return 1; +} + +/* +> success = RL.SetModelAnimationFramePose( ModelAnimation animation, int frame, int boneId, Transform pose ) + +Set modelAnimation bones base transformation (pose) + +- Failure return false +- Success return true +*/ +int lmodelsSetModelAnimationFramePose( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + int frame = luaL_checkinteger( L, 2 ); + int boneId = luaL_checkinteger( L, 3 ); + Transform pose = uluaGetTransform( L, 4 ); + + if ( 0 <= frame && frame < animation->frameCount && 0 <= boneId && boneId < animation->boneCount ) { + animation->framePoses[ frame ][ boneId ] = pose; + lua_pushboolean( L, true ); + } + else { + TraceLog( LOG_WARNING, "SetModelAnimationFramePose frame %d or BoneId %d out of bounds", frame, boneId ); + lua_pushboolean( L, false ); + } + return 1; +} + +/* +> RL.SetModelAnimationName( ModelAnimation animation, string name ) + +Set modelAnimation name +*/ +int lmodelsSetModelAnimationName( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + const char *name = luaL_checkstring( L, 2 ); + + strncpy( animation->name, name, 32 ); return 1; } @@ -2026,6 +2090,66 @@ int lmodelsGetModelAnimationFrameCount( lua_State *L ) { } /* +> bone = RL.GetModelAnimationBone( ModelAnimation animation, int boneId ) + +Get modelAnimation bones information (skeleton) + +- Failure return nil +- Success return BoneInfo +*/ +int lmodelsGetModelAnimationBone( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + int boneId = luaL_checkinteger( L, 2 ); + + if ( 0 <= boneId && boneId < animation->boneCount ) { + uluaPushBoneInfo( L, animation->bones[ boneId ] ); + } + else { + TraceLog( LOG_WARNING, "GetModelAnimationBone boneId %d out of bounds", boneId ); + lua_pushnil( L ); + } + return 1; +} + +/* +> pose = RL.GetModelAnimationFramePose( ModelAnimation animation, int frame, int boneId ) + +Get modelAnimation bones base transformation (pose) + +- Failure return nil +- Success return Transform +*/ +int lmodelsGetModelAnimationFramePose( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + int frame = luaL_checkinteger( L, 2 ); + int boneId = luaL_checkinteger( L, 3 ); + + if ( 0 <= frame && frame < animation->frameCount && 0 <= boneId && boneId < animation->boneCount ) { + uluaPushTransform( L, animation->framePoses[ frame ][ boneId ] ); + } + else { + TraceLog( LOG_WARNING, "GetModelAnimationFramePose frame %d or BoneId %d out of bounds", frame, boneId ); + lua_pushnil( L ); + } + return 1; +} + +/* +> name = RL.GetModelAnimationName( ModelAnimation animation ) + +Get modelAnimation name + +- Success return string +*/ +int lmodelsGetModelAnimationName( lua_State *L ) { + ModelAnimation *animation = uluaGetModelAnimation( L, 1 ); + + lua_pushstring( L, animation->name ); + + return 1; +} + +/* ## Model - Collision detection functions */ |
