From ef75e2530dd92c55ba6b2462fe71fa888e1883df Mon Sep 17 00:00:00 2001 From: jussi Date: Thu, 9 Nov 2023 20:48:16 +0200 Subject: GenMeshCubicmap, Organized model functions, GetModelBoundingBox, DrawModelWires and DrawModelWiresEx and LoadMaterials. --- src/models.c | 1116 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 612 insertions(+), 504 deletions(-) (limited to 'src/models.c') diff --git a/src/models.c b/src/models.c index 2db4b5b..9ff64d8 100644 --- a/src/models.c +++ b/src/models.c @@ -127,7 +127,7 @@ void DrawBillboardRecNoRatio( Camera camera, Texture2D texture, Rectangle source } /* -## Models - Basic +## Models - Basic geometric 3D shapes drawing functions */ /* @@ -491,7 +491,569 @@ int lmodelsDrawGrid( lua_State *L ) { } /* -## Models - Mesh +## Models - Model management functions +*/ + +/* +> model = RL.LoadModel( string fileName ) + +Load model from files (Meshes and materials) + +- Failure return nil +- Success return Model +*/ +int lmodelsLoadModel( lua_State *L ) { + if ( FileExists( luaL_checkstring( L, 1 ) ) ) { + uluaPushModel( L, LoadModel( lua_tostring( L, 1 ) ) ); + + return 1; + } + TraceLog( state->logLevelInvalid, "Invalid file '%s'", lua_tostring( L, 1 ) ); + lua_pushnil( L ); + + return 1; +} + +/* +> model = RL.LoadModelFromMesh( Mesh mesh ) + +Load model from generated mesh (Default material) + +- Success return Model +*/ +int lmodelsLoadModelFromMesh( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + + uluaPushModel( L, LoadModelFromMesh( *mesh ) ); + + return 1; +} + +/* +> isReady = RL.IsModelReady( Model model ) + +Check if a model is ready + +- Success return bool +*/ +int lmodelsIsModelReady( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + + lua_pushboolean( L, IsModelReady( *model ) ); + + return 1; +} + +/* +> RL.UnloadModel( Model model ) + +Unload model (including meshes) from memory (RAM and/or VRAM) +*/ +int lmodelsUnloadModel( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + + UnloadModel( *model ); + + return 0; +} + +/* +> boundingBox = RL.GetModelBoundingBox( Model model ) + +Compute model bounding box limits (considers all meshes) + +- Success return BoundingBox +*/ +int lmodelsGetModelBoundingBox( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + + uluaPushBoundingBox( L, GetModelBoundingBox( *model ) ); + + return 1; +} + +/* +> RL.SetModelMaterial( Model model, Material modelMaterial, Material material ) + +Copies material to model material. (Model material is the material id in models.) +*/ +int lmodelsSetModelMaterial( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + int modelMaterialId = luaL_checkinteger( L, 2 ); + Material *material = uluaGetMaterial( L, 3 ); + + //TODO Could maybe return old shader and textures for storage or get garbage collected? + + /* 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]; + } + + return 0; +} + +/* +> RL.SetModelMeshMaterial( Model model, int meshId, int materialId ) + +Set material for a mesh (Mesh and material on this model) +*/ +int lmodelsSetModelMeshMaterial( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + int meshId = luaL_checkinteger( L, 2 ); + int materialId = luaL_checkinteger( L, 3 ); + + SetModelMeshMaterial( model, meshId, materialId ); + + return 0; +} + +/* +> RL.SetModelTransform( Model model, Matrix transform ) + +Set model transform matrix +*/ +int lmodelsSetModelTransform( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + Matrix transform = uluaGetMatrix( L, 2 ); + + model->transform = transform; + + return 0; +} + +/* +> transform = RL.GetModelTransform( Model model ) + +Get model transform matrix + +- Success return Matrix +*/ +int lmodelsGetModelTransform( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + + uluaPushMatrix( L, model->transform ); + + return 1; +} + +/* +## Models - Model drawing functions +*/ + +/* +> RL.DrawModel( Model model, Vector3 position, float scale, Color tint ) + +Draw a model (With texture if set) +*/ +int lmodelsDrawModel( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + Vector3 position = uluaGetVector3( L, 2 ); + float scale = luaL_checknumber( L, 3 ); + Color tint = uluaGetColor( L, 4 ); + + DrawModel( *model, position, scale, tint ); + + return 0; +} + +/* +> RL.DrawModelEx( Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint ) + +Draw a model with extended parameters +*/ +int lmodelsDrawModelEx( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + Vector3 position = uluaGetVector3( L, 2 ); + Vector3 rotationAxis = uluaGetVector3( L, 3 ); + float rotationAngle = luaL_checknumber( L, 4 ); + Vector3 scale = uluaGetVector3( L, 5 ); + Color tint = uluaGetColor( L, 6 ); + + DrawModelEx( *model, position, rotationAxis, rotationAngle, scale, tint ); + + return 0; +} + +/* +> RL.DrawModelWires( Model model, Vector3 position, float scale, Color tint ) + +Draw a model wires (with texture if set) +*/ +int lmodelsDrawModelWires( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + Vector3 position = uluaGetVector3( L, 2 ); + float scale = luaL_checknumber( L, 3 ); + Color tint = uluaGetColor( L, 4 ); + + DrawModelWires( *model, position, scale, tint ); + + return 0; +} + +/* +> RL.DrawModelWiresEx( Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint ) + +Draw a model wires (with texture if set) with extended parameters +*/ +int lmodelsDrawModelWiresEx( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + Vector3 position = uluaGetVector3( L, 2 ); + Vector3 rotationAxis = uluaGetVector3( L, 3 ); + float rotationAngle = luaL_checknumber( L, 4 ); + Vector3 scale = uluaGetVector3( L, 5 ); + Color tint = uluaGetColor( L, 6 ); + + DrawModelWiresEx( *model, position, rotationAxis, rotationAngle, scale, tint ); + + return 0; +} + +/* +> RL.DrawBoundingBox( BoundingBox box, Color color ) + +Draw bounding box (wires) +*/ +int lmodelsDrawBoundingBox( lua_State *L ) { + BoundingBox box = uluaGetBoundingBox( L, 1 ); + Color color = uluaGetColor( L, 2 ); + + DrawBoundingBox( box, color ); + + return 0; +} + +/* +> RL.DrawBillboard( Camera3D camera, Texture texture, Vector3 position, float size, Color tint ) + +Draw a billboard texture +*/ +int lmodelsDrawBillboard( lua_State *L ) { + Camera3D *camera = uluaGetCamera3D( L, 1 ); + Texture *texture = uluaGetTexture( L, 2 ); + Vector3 position = uluaGetVector3( L, 3 ); + float size = luaL_checknumber( L, 4 ); + Color tint = uluaGetColor( L, 5 ); + + DrawBillboard( *camera, *texture, position, size, tint ); + + return 0; +} + +/* +> RL.DrawBillboardRec( Camera3D camera, Texture texture, Rectangle source, Vector3 position, Vector2 size, Color tint ) + +Draw a billboard texture defined by source +*/ +int lmodelsDrawBillboardRec( lua_State *L ) { + Camera3D *camera = uluaGetCamera3D( L, 1 ); + Texture *texture = uluaGetTexture( L, 2 ); + Rectangle source = uluaGetRectangle( L, 3 ); + Vector3 position = uluaGetVector3( L, 4 ); + Vector2 size = uluaGetVector2( L, 5 ); + Color tint = uluaGetColor( L, 6 ); + + DrawBillboardRecNoRatio( *camera, *texture, source, position, size, tint ); + + return 0; +} + +/* +> RL.DrawBillboardPro( Camera3D camera, Texture texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) + +Draw a billboard texture defined by source and rotation +*/ +int lmodelsDrawBillboardPro( lua_State *L ) { + Camera3D *camera = uluaGetCamera3D( L, 1 ); + Texture *texture = uluaGetTexture( L, 2 ); + Rectangle source = uluaGetRectangle( L, 3 ); + Vector3 position = uluaGetVector3( L, 4 ); + Vector3 up = uluaGetVector3( L, 5 ); + Vector2 size = uluaGetVector2( L, 6 ); + Vector2 origin = uluaGetVector2( L, 7 ); + float rotation = luaL_checknumber( L, 8 ); + Color tint = uluaGetColor( L, 9 ); + + DrawBillboardProNoRatio( *camera, *texture, source, position, up, size, origin, rotation, tint ); + + return 0; +} + +/* +## Models - Mesh management functions +*/ + +/* +> RL.UpdateMesh( Mesh mesh, Mesh{} meshData ) + +Update mesh vertex data in GPU. +Note! Mainly intented to be used with custom meshes. +*/ +int lmodelsUpdateMesh( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + luaL_checktype( L, 2, LUA_TTABLE ); + + int t = 2; + lua_pushnil( L ); + + while ( lua_next( L, t ) != 0 ) { + if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + Vector3 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 && i < mesh->vertexCount ) { + data[i] = uluaGetVector3( L, lua_gettop( L ) ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 0, (void*)data, len * 3 * sizeof( float ), 0 ); + } + else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + Vector2 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector2( L, lua_gettop( L ) ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 1, (void*)data, len * 2 * sizeof( float ), 0 ); + } + else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + Vector2 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector2( L, lua_gettop( L ) ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 5, (void*)data, len * 2 * sizeof( float ), 0 ); + } + else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + Vector3 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector3( L, lua_gettop( L ) ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 2, (void*)data, len * 3 * sizeof( float ), 0 ); + } + else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + Vector4 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector4( L, lua_gettop( L ) ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 4, (void*)data, len * 4 * sizeof( float ), 0 ); + } + else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + Color data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetColor( L, lua_gettop( L ) ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 3, (void*)data, len * 4 * sizeof( unsigned char ), 0 ); + } + else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L, lua_gettop( L ) ); + unsigned short data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = (unsigned short)lua_tointeger( L, -1 ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 6, (void*)data, len * sizeof( unsigned short ), 0 ); + } + lua_pop( L, 1 ); + } + + return 0; +} + +/* +> RL.UnloadMesh( Mesh mesh ) + +Unload mesh data from CPU and GPU +*/ +int lmodelsUnloadMesh( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + + UnloadMesh( *mesh ); + + return 0; +} + +/* +> RL.DrawMesh( Mesh mesh, Material material, Matrix transform ) + +Draw a 3d mesh with material and transform +*/ +int lmodelsDrawMesh( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + Material *material = uluaGetMaterial( L, 2 ); + Matrix matrix = uluaGetMatrix( L, 3 ); + + DrawMesh( *mesh, *material, matrix ); + + return 0; +} + +/* +> RL.DrawMeshInstanced( Mesh mesh, Material material, Matrix{} transforms, int instances ) + +Draw multiple mesh instances with material and different transforms +*/ +int lmodelsDrawMeshInstanced( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + Material *material = uluaGetMaterial( L, 2 ); + luaL_checktype( L, 3, LUA_TTABLE ); + int instances = luaL_checkinteger( L, 4 ); + + Matrix transforms[ instances ]; + + int t = 3, i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t ) != 0 ) { + if ( lua_istable( L, -1 ) ) { + transforms[i] = uluaGetMatrix( L, lua_gettop( L ) ); + } + i++; + lua_pop( L, 1 ); + } + DrawMeshInstanced( *mesh, *material, transforms, instances ); + + return 0; +} + +/* +> success = RL.SetMeshColor( Mesh mesh, Color color ) + +Updades mesh color vertex attribute buffer +NOTE: Currently only works on custom mesh + +- Failure return false +- Success return true +*/ +int lmodelsSetMeshColor( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + Color color = uluaGetColor( L, 2 ); + + if ( mesh->colors == NULL ) { + TraceLog( state->logLevelInvalid, "Mesh doesn't have vertex colors allocated" ); + lua_pushboolean( L, false ); + return 1; + } + + for ( int i = 0; i < mesh->vertexCount; ++i ) { + mesh->colors[(i*4)+0] = (unsigned char)color.r; + mesh->colors[(i*4)+1] = (unsigned char)color.g; + mesh->colors[(i*4)+2] = (unsigned char)color.b; + mesh->colors[(i*4)+3] = (unsigned char)color.a; + } + /* Update vertex attribute: color */ + rlUpdateVertexBuffer( mesh->vboId[3], mesh->colors, mesh->vertexCount * 4 * sizeof( unsigned char ), 0 ); + + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.ExportMesh( Mesh mesh, string fileName ) + +Export mesh data to file, returns true on success + +- Success return bool +*/ +int lmodelsExportMesh( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + + lua_pushboolean( L, ExportMesh( *mesh, luaL_checkstring( L, 2 ) ) ); + + return 1; +} + +/* +> boundingBox = RL.GetMeshBoundingBox( Mesh mesh ) + +Compute mesh bounding box limits + +- Success return BoundingBox +*/ +int lmodelsGetMeshBoundingBox( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + + uluaPushBoundingBox( L, GetMeshBoundingBox( *mesh ) ); + + return 1; +} + +/* +> RL.GenMeshTangents( Mesh mesh ) + +Compute mesh tangents +*/ +int lmodelsGenMeshTangents( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + + GenMeshTangents( mesh ); + + return 0; +} + +/* +## Models - Mesh generation functions */ /* @@ -637,11 +1199,27 @@ Generate heightmap mesh from image data - Success return Mesh */ -int lmodelsGenMeshHeightmap( lua_State *L ) { - Image *heightmap = uluaGetImage( L, 1 ); - Vector3 size = uluaGetVector3( L, 2 ); +int lmodelsGenMeshHeightmap( lua_State *L ) { + Image *heightmap = uluaGetImage( L, 1 ); + Vector3 size = uluaGetVector3( L, 2 ); + + uluaPushMesh( L, GenMeshHeightmap( *heightmap, size ) ); + + return 1; +} + +/* +> mesh = RL.GenMeshCubicmap( Image cubicmap, Vector3 cubeSize ) + +Generate cubes-based map mesh from image data + +- Success return Mesh +*/ +int lmodelsGenMeshCubicmap( lua_State *L ) { + Image *cubicmap = uluaGetImage( L, 1 ); + Vector3 cubeSize = uluaGetVector3( L, 2 ); - uluaPushMesh( L, GenMeshHeightmap( *heightmap, size ) ); + uluaPushMesh( L, GenMeshCubicmap( *cubicmap, cubeSize ) ); return 1; } @@ -790,278 +1368,42 @@ int lmodelsGenMeshCustom( lua_State *L ) { while ( lua_next( L, t2 ) != 0 ) { mesh.indices[i] = (unsigned short)lua_tointeger( L, -1 ); - i++; - lua_pop( L, 1 ); - } - } - lua_pop( L, 1 ); - } - UploadMesh( &mesh, dynamic ); - uluaPushMesh( L, mesh ); - - return 1; -} - -/* -> RL.UpdateMesh( Mesh mesh, Mesh{} meshData ) - -Update mesh vertex data in GPU. -Note! Mainly intented to be used with custom meshes. -*/ -int lmodelsUpdateMesh( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - luaL_checktype( L, 2, LUA_TTABLE ); - - int t = 2; - lua_pushnil( L ); - - while ( lua_next( L, t ) != 0 ) { - if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - Vector3 data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 && i < mesh->vertexCount ) { - data[i] = uluaGetVector3( L, lua_gettop( L ) ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 0, (void*)data, len * 3 * sizeof( float ), 0 ); - } - else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - Vector2 data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 ) { - data[i] = uluaGetVector2( L, lua_gettop( L ) ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 1, (void*)data, len * 2 * sizeof( float ), 0 ); - } - else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - Vector2 data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 ) { - data[i] = uluaGetVector2( L, lua_gettop( L ) ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 5, (void*)data, len * 2 * sizeof( float ), 0 ); - } - else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - Vector3 data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 ) { - data[i] = uluaGetVector3( L, lua_gettop( L ) ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 2, (void*)data, len * 3 * sizeof( float ), 0 ); - } - else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - Vector4 data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 ) { - data[i] = uluaGetVector4( L, lua_gettop( L ) ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 4, (void*)data, len * 4 * sizeof( float ), 0 ); - } - else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - Color data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 ) { - data[i] = uluaGetColor( L, lua_gettop( L ) ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 3, (void*)data, len * 4 * sizeof( unsigned char ), 0 ); - } - else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { - size_t len = uluaGetTableLen( L, lua_gettop( L ) ); - unsigned short data[ len ]; - - int t2 = lua_gettop( L ); - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t2 ) != 0 ) { - data[i] = (unsigned short)lua_tointeger( L, -1 ); - i++; - lua_pop( L, 1 ); - } - UpdateMeshBuffer( *mesh, 6, (void*)data, len * sizeof( unsigned short ), 0 ); - } - lua_pop( L, 1 ); - } - - return 0; -} - -/* -> RL.UnloadMesh( Mesh mesh ) - -Unload mesh data from CPU and GPU -*/ -int lmodelsUnloadMesh( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - - UnloadMesh( *mesh ); - - return 0; -} - -/* -> RL.DrawMesh( Mesh mesh, Material material, Matrix transform ) - -Draw a 3d mesh with material and transform -*/ -int lmodelsDrawMesh( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - Material *material = uluaGetMaterial( L, 2 ); - Matrix matrix = uluaGetMatrix( L, 3 ); - - DrawMesh( *mesh, *material, matrix ); - - return 0; -} - -/* -> RL.DrawMeshInstanced( Mesh mesh, Material material, Matrix{} transforms, int instances ) - -Draw multiple mesh instances with material and different transforms -*/ -int lmodelsDrawMeshInstanced( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - Material *material = uluaGetMaterial( L, 2 ); - luaL_checktype( L, 3, LUA_TTABLE ); - int instances = luaL_checkinteger( L, 4 ); - - Matrix transforms[ instances ]; - - int t = 3, i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - transforms[i] = uluaGetMatrix( L, lua_gettop( L ) ); - } - i++; - lua_pop( L, 1 ); - } - DrawMeshInstanced( *mesh, *material, transforms, instances ); - - return 0; -} - -/* -> success = RL.SetMeshColor( Mesh mesh, Color color ) - -Updades mesh color vertex attribute buffer -NOTE: Currently only works on custom mesh - -- Failure return false -- Success return true -*/ -int lmodelsSetMeshColor( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - Color color = uluaGetColor( L, 2 ); - - if ( mesh->colors == NULL ) { - TraceLog( state->logLevelInvalid, "Mesh doesn't have vertex colors allocated" ); - lua_pushboolean( L, false ); - return 1; - } - - for ( int i = 0; i < mesh->vertexCount; ++i ) { - mesh->colors[(i*4)+0] = (unsigned char)color.r; - mesh->colors[(i*4)+1] = (unsigned char)color.g; - mesh->colors[(i*4)+2] = (unsigned char)color.b; - mesh->colors[(i*4)+3] = (unsigned char)color.a; - } - /* Update vertex attribute: color */ - rlUpdateVertexBuffer( mesh->vboId[3], mesh->colors, mesh->vertexCount * 4 * sizeof( unsigned char ), 0 ); - - lua_pushboolean( L, true ); - - return 1; -} - -/* -> success = RL.ExportMesh( Mesh mesh, string fileName ) - -Export mesh data to file, returns true on success - -- Success return bool -*/ -int lmodelsExportMesh( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - - lua_pushboolean( L, ExportMesh( *mesh, luaL_checkstring( L, 2 ) ) ); - - return 1; -} - -/* -> boundingBox = RL.GetMeshBoundingBox( Mesh mesh ) - -Compute mesh bounding box limits - -- Success return BoundingBox -*/ -int lmodelsGetMeshBoundingBox( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - - uluaPushBoundingBox( L, GetMeshBoundingBox( *mesh ) ); + i++; + lua_pop( L, 1 ); + } + } + lua_pop( L, 1 ); + } + UploadMesh( &mesh, dynamic ); + uluaPushMesh( L, mesh ); return 1; } /* -> RL.GenMeshTangents( Mesh mesh ) - -Compute mesh tangents +## Models - Material management functions */ -int lmodelsGenMeshTangents( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - GenMeshTangents( mesh ); +/* +> materials = RL.LoadMaterials( string fileName ) - return 0; -} +Load materials from model file -/* -## Models - Material +- Success return Material{} */ +int lmodelsLoadMaterials( lua_State *L ) { + const char *fileName = luaL_checkstring( L, 1 ); + + int materialCount = 0; + Material *materials = LoadMaterials( fileName, &materialCount ); + lua_createtable( L, materialCount, 0 ); + + for ( int i = 0; i < materialCount; i++ ) { + uluaPushMaterial( L, materials[i] ); + lua_rawseti( L, -2, i + 1 ); + } + return 1; +} /* > material = RL.GetMaterialDefault() @@ -1379,241 +1721,7 @@ int lmodelsGetMaterialParams( lua_State *L ) { } /* -## Models - Model -*/ - -/* -> model = RL.LoadModel( string fileName ) - -Load model from files (Meshes and materials) - -- Failure return nil -- Success return Model -*/ -int lmodelsLoadModel( lua_State *L ) { - if ( FileExists( luaL_checkstring( L, 1 ) ) ) { - uluaPushModel( L, LoadModel( lua_tostring( L, 1 ) ) ); - - return 1; - } - TraceLog( state->logLevelInvalid, "Invalid file '%s'", lua_tostring( L, 1 ) ); - lua_pushnil( L ); - - return 1; -} - -/* -> model = RL.LoadModelFromMesh( Mesh mesh ) - -Load model from generated mesh (Default material) - -- Success return Model -*/ -int lmodelsLoadModelFromMesh( lua_State *L ) { - Mesh *mesh = uluaGetMesh( L, 1 ); - - uluaPushModel( L, LoadModelFromMesh( *mesh ) ); - - return 1; -} - -/* -> isReady = RL.IsModelReady( Model model ) - -Check if a model is ready - -- Success return bool -*/ -int lmodelsIsModelReady( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - - lua_pushboolean( L, IsModelReady( *model ) ); - - return 1; -} - -/* -> RL.UnloadModel( Model model ) - -Unload model (including meshes) from memory (RAM and/or VRAM) -*/ -int lmodelsUnloadModel( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - - UnloadModel( *model ); - - return 0; -} - -/* -> RL.DrawModel( Model model, Vector3 position, float scale, Color tint ) - -Draw a model (With texture if set) -*/ -int lmodelsDrawModel( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - Vector3 position = uluaGetVector3( L, 2 ); - float scale = luaL_checknumber( L, 3 ); - Color tint = uluaGetColor( L, 4 ); - - DrawModel( *model, position, scale, tint ); - - return 0; -} - -/* -> RL.DrawModelEx( Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint ) - -Draw a model with extended parameters -*/ -int lmodelsDrawModelEx( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - Vector3 position = uluaGetVector3( L, 2 ); - Vector3 rotationAxis = uluaGetVector3( L, 3 ); - float rotationAngle = luaL_checknumber( L, 4 ); - Vector3 scale = uluaGetVector3( L, 5 ); - Color tint = uluaGetColor( L, 6 ); - - DrawModelEx( *model, position, rotationAxis, rotationAngle, scale, tint ); - - return 0; -} - -/* -> RL.SetModelMaterial( Model model, Material modelMaterial, Material material ) - -Copies material to model material. (Model material is the material id in models.) -*/ -int lmodelsSetModelMaterial( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - int modelMaterialId = luaL_checkinteger( L, 2 ); - Material *material = uluaGetMaterial( L, 3 ); - - //TODO Could maybe return old shader and textures for storage or get garbage collected? - - /* 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]; - } - - return 0; -} - -/* -> RL.SetModelMeshMaterial( Model model, int meshId, int materialId ) - -Set material for a mesh (Mesh and material on this model) -*/ -int lmodelsSetModelMeshMaterial( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - int meshId = luaL_checkinteger( L, 2 ); - int materialId = luaL_checkinteger( L, 3 ); - - SetModelMeshMaterial( model, meshId, materialId ); - - return 0; -} - -/* -> RL.DrawBillboard( Camera3D camera, Texture texture, Vector3 position, float size, Color tint ) - -Draw a billboard texture -*/ -int lmodelsDrawBillboard( lua_State *L ) { - Camera3D *camera = uluaGetCamera3D( L, 1 ); - Texture *texture = uluaGetTexture( L, 2 ); - Vector3 position = uluaGetVector3( L, 3 ); - float size = luaL_checknumber( L, 4 ); - Color tint = uluaGetColor( L, 5 ); - - DrawBillboard( *camera, *texture, position, size, tint ); - - return 0; -} - -/* -> RL.DrawBillboardRec( Camera3D camera, Texture texture, Rectangle source, Vector3 position, Vector2 size, Color tint ) - -Draw a billboard texture defined by source -*/ -int lmodelsDrawBillboardRec( lua_State *L ) { - Camera3D *camera = uluaGetCamera3D( L, 1 ); - Texture *texture = uluaGetTexture( L, 2 ); - Rectangle source = uluaGetRectangle( L, 3 ); - Vector3 position = uluaGetVector3( L, 4 ); - Vector2 size = uluaGetVector2( L, 5 ); - Color tint = uluaGetColor( L, 6 ); - - DrawBillboardRecNoRatio( *camera, *texture, source, position, size, tint ); - - return 0; -} - -/* -> RL.DrawBillboardPro( Camera3D camera, Texture texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint ) - -Draw a billboard texture defined by source and rotation -*/ -int lmodelsDrawBillboardPro( lua_State *L ) { - Camera3D *camera = uluaGetCamera3D( L, 1 ); - Texture *texture = uluaGetTexture( L, 2 ); - Rectangle source = uluaGetRectangle( L, 3 ); - Vector3 position = uluaGetVector3( L, 4 ); - Vector3 up = uluaGetVector3( L, 5 ); - Vector2 size = uluaGetVector2( L, 6 ); - Vector2 origin = uluaGetVector2( L, 7 ); - float rotation = luaL_checknumber( L, 8 ); - Color tint = uluaGetColor( L, 9 ); - - DrawBillboardProNoRatio( *camera, *texture, source, position, up, size, origin, rotation, tint ); - - return 0; -} - -/* -> RL.SetModelTransform( Model model, Matrix transform ) - -Set model transform matrix -*/ -int lmodelsSetModelTransform( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - Matrix transform = uluaGetMatrix( L, 2 ); - - model->transform = transform; - - return 0; -} - -/* -> transform = RL.GetModelTransform( Model model ) - -Get model transform matrix - -- Success return Matrix -*/ -int lmodelsGetModelTransform( lua_State *L ) { - Model *model = uluaGetModel( L, 1 ); - - uluaPushMatrix( L, model->transform ); - - return 1; -} - -/* -## Model - Animations +## Model - Model animations management functions */ /* @@ -1706,7 +1814,7 @@ int lmodelsGetModelAnimationFrameCount( lua_State *L ) { } /* -## Model - Collision +## Model - Collision detection functions */ /* -- cgit v1.2.3