From 59ea29d8ff9dad751659a0a42d76a5534f7b4b97 Mon Sep 17 00:00:00 2001 From: jussi Date: Mon, 16 May 2022 13:44:10 +0300 Subject: [PATCH] New GenMeshCustom, UpdateMesh and lightmap example. --- API.md | 27 +- doc_parser.lua | 15 +- examples/heightmap/main.lua | 3 + examples/lightmap/main.lua | 92 ++++ examples/resources/images/lightmap.png | Bin 0 -> 717 bytes examples/resources/images/tile.png | Bin 0 -> 3043 bytes .../resources/shaders/glsl330/lightmap.fs | 22 + .../resources/shaders/glsl330/lightmap.vs | 31 ++ include/models.h | 1 + src/lua_core.c | 1 + src/models.c | 447 ++++++++++++------ 11 files changed, 493 insertions(+), 146 deletions(-) create mode 100644 examples/lightmap/main.lua create mode 100644 examples/resources/images/lightmap.png create mode 100644 examples/resources/images/tile.png create mode 100644 examples/resources/shaders/glsl330/lightmap.fs create mode 100644 examples/resources/shaders/glsl330/lightmap.vs diff --git a/API.md b/API.md index b4e23f4..486e1cf 100644 --- a/API.md +++ b/API.md @@ -635,6 +635,18 @@ int id. Defines 3d camera position/orientation int id. Vertex data defining a mesh +``` +mesh{} = { + vertices = { Vector3, ... }, + texcoords = { Vector2, ... }, + texcoords2 = { Vector2, ... }, + normals = { Vector3, ... }, + tangents = { Vector4, ... }, + colors = { Color, ... }, + indices = { int, ... }, +} +``` + --- > Material = MaterialId @@ -642,7 +654,7 @@ int id. Vertex data defining a mesh int id. Material type ``` -table = { +material{} = { shader = Shader, maps = { { @@ -3200,15 +3212,24 @@ Generate heightmap mesh from image data --- -> mesh = RL_GenMeshCustom( Vector3{} vertices, Vector2{} texCoords, Vector3{} normals ) +> mesh = RL_GenMeshCustom( Mesh{}, bool dynamic ) -Generate custom mesh +Generate custom mesh from vertex attribute data and uploads it into a VAO ( if supported ) and VBO - Failure return -1 - Success return int --- +> success = RL_UpdateMesh( Mesh{} ) + +Update mesh vertex data in GPU. ( Mainly intented to be used with custom meshes ) + +- Failure return false +- Success return true + +--- + > success = RL_UnloadMesh( Mesh mesh ) Unload mesh data from CPU and GPU diff --git a/doc_parser.lua b/doc_parser.lua index 19b69c9..a32ed7b 100644 --- a/doc_parser.lua +++ b/doc_parser.lua @@ -95,11 +95,22 @@ int id. Font type, includes texture and chars data\n\n---\n" ) apiFile:write( "\n> Camera = CameraId\n\ int id. Defines 3d camera position/orientation\n\n---\n" ) apiFile:write( "\n> Mesh = MeshId\n\ -int id. Vertex data defining a mesh\n\n---\n" ) +int id. Vertex data defining a mesh\n\ +```\ +mesh{} = {\ + vertices = { Vector3, ... },\ + texcoords = { Vector2, ... },\ + texcoords2 = { Vector2, ... },\ + normals = { Vector3, ... },\ + tangents = { Vector4, ... },\ + colors = { Color, ... },\ + indices = { int, ... },\ +}\ +```\n\n---\n" ) apiFile:write( "\n> Material = MaterialId\n\ int id. Material type\n\ ```\ -table = {\ +material{} = {\ shader = Shader,\ maps = {\ {\ diff --git a/examples/heightmap/main.lua b/examples/heightmap/main.lua index ecc6993..899ab72 100644 --- a/examples/heightmap/main.lua +++ b/examples/heightmap/main.lua @@ -7,6 +7,7 @@ local tilesetTex = -1 local heigthImage = -1 local mesh = -1 local material = -1 +local lightmap = -1 local grassRec = { 6 * TILE_SIZE, 0 * TILE_SIZE, TILE_SIZE, TILE_SIZE } local dirtRec = { 4 * TILE_SIZE, 0 * TILE_SIZE, TILE_SIZE, TILE_SIZE } @@ -64,6 +65,8 @@ function init() material = RL_LoadMaterialDefault() RL_SetTextureSource( TEXTURE_SOURCE_RENDER_TEXTURE ) + -- RL_GenTextureMipmaps( groundTexture ) + -- RL_SetTextureFilter( groundTexture, TEXTURE_FILTER_TRILINEAR ) RL_SetMaterialTexture( material, MATERIAL_MAP_ALBEDO, groundTexture ) RL_SetTextureSource( TEXTURE_SOURCE_TEXTURE ) diff --git a/examples/lightmap/main.lua b/examples/lightmap/main.lua new file mode 100644 index 0000000..eb81d96 --- /dev/null +++ b/examples/lightmap/main.lua @@ -0,0 +1,92 @@ +local PLANE_SIZE = 8 + +local monitor = 0 +local camera = -1 +local tileTexture = -1 +local mesh = -1 +local material = -1 +local lightmap = -1 +local shader = -1 + +local matrix = {} + +function init() + local mPos = RL_GetMonitorPosition( monitor ) + local mSize = RL_GetMonitorSize( monitor ) + local winSize = RL_GetWindowSize() + + RL_SetWindowState( FLAG_WINDOW_RESIZABLE ) + RL_SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } ) + + camera = RL_CreateCamera3D() + RL_SetCamera3DPosition( camera, { 0, 8, 16 } ) + RL_SetCamera3DTarget( camera, { 0, 0, 0 } ) + RL_SetCamera3DUp( camera, { 0, 2, 0 } ) + RL_SetCamera3DMode( camera, CAMERA_FREE ) + + local ts = PLANE_SIZE + local meshData = { + vertices = { { 0, 0, 0 }, { 0, 0, PLANE_SIZE }, { PLANE_SIZE, 0, PLANE_SIZE }, + { 0, 0, 0 }, { PLANE_SIZE, 0, PLANE_SIZE }, { PLANE_SIZE, 0, 0 } }, + texcoords = { { 0, 0 }, { 0, ts }, { ts, ts }, + { 0, 0 }, { ts, ts }, { ts, 0 } }, + texcoords2 = { { 0, 0 }, { 0, 1 }, { 1, 1 }, + { 0, 0 }, { 1, 1 }, { 1, 0 } }, + colors = { WHITE, WHITE, WHITE, + WHITE, WHITE, WHITE }, + normals = { { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, + { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 } }, + } + mesh = RL_GenMeshCustom( meshData, true ) + + -- local meshEdit = { + -- vertices = { { 0, 1, 0 }, { 0, 0, PLANE_SIZE }, { PLANE_SIZE, 0, PLANE_SIZE }, + -- { 0, 1, 0 }, { PLANE_SIZE, 0, PLANE_SIZE }, { PLANE_SIZE, 0, 0 } }, + -- } + -- RL_UpdateMesh( mesh, meshEdit ) + + tileTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/tile.png" ) + RL_GenTextureMipmaps( tileTexture ) + RL_SetTextureFilter( tileTexture, TEXTURE_FILTER_TRILINEAR ) + lightmap = RL_LoadTexture( RL_GetBasePath().."../resources/images/lightmap.png" ) + RL_GenTextureMipmaps( lightmap ) + RL_SetTextureFilter( lightmap, TEXTURE_FILTER_TRILINEAR ) + RL_SetTextureWrap( lightmap, TEXTURE_WRAP_CLAMP ) + + shader = RL_LoadShader( RL_GetBasePath().."../resources/shaders/glsl330/lightmap.vs", + RL_GetBasePath().."../resources/shaders/glsl330/lightmap.fs" ) + + local materialData = { + shader = shader, + maps = { + { + MATERIAL_MAP_ALBEDO, + { + texture = tileTexture, + color = WHITE, + value = 1.0, + }, + }, + { + MATERIAL_MAP_METALNESS, + { + texture = lightmap, + color = WHITE, + value = 1.0, + }, + }, + }, + } + material = RL_CreateMaterial( materialData ) + + matrix = RL_MatrixMultiply( RL_MatrixIdentity(), RL_MatrixTranslate( { -4, 0, -4 } ) ) +end + +function draw() + RL_ClearBackground( { 25, 50, 50 } ) + RL_UpdateCamera3D( camera ) + + RL_BeginMode3D( camera ) + RL_DrawMesh( mesh, material, matrix ) + RL_EndMode3D() +end diff --git a/examples/resources/images/lightmap.png b/examples/resources/images/lightmap.png new file mode 100644 index 0000000000000000000000000000000000000000..35754e62c10d604893171796085cc01ce0503d4d GIT binary patch literal 717 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 i++ ) { + if ( state->meshes[i] == NULL ) { + break; + } + } + state->meshes[i] = malloc( sizeof( Mesh ) ); + checkMeshRealloc( i ); + + return i; +} + /* ## Models - Basic */ @@ -683,14 +697,8 @@ int lmodelsGenMeshPoly( lua_State *L ) { } float radius = lua_tonumber( L, -1 ); int sides = lua_tointeger( L, -2 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshPoly( sides, radius ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -716,14 +724,8 @@ int lmodelsGenMeshPlane( lua_State *L ) { int resX = lua_tointeger( L, -2 ); float length = lua_tonumber( L, -3 ); float width = lua_tonumber( L, -4 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshPlane( width, length, resX, resZ ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -746,14 +748,8 @@ int lmodelsGenMeshCube( lua_State *L ) { return 1; } Vector3 size = uluaGetVector3( L ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshCube( size.x, size.y, size.z ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -778,14 +774,8 @@ int lmodelsGenMeshSphere( lua_State *L ) { int slices = lua_tointeger( L, -1 ); int rings = lua_tointeger( L, -2 ); float radius = lua_tonumber( L, -3 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshSphere( radius, rings, slices ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -810,14 +800,8 @@ int lmodelsGenMeshCylinder( lua_State *L ) { int slices = lua_tointeger( L, -1 ); float height = lua_tonumber( L, -2 ); float radius = lua_tonumber( L, -3 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshCylinder( radius, height, slices); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -842,14 +826,8 @@ int lmodelsGenMeshCone( lua_State *L ) { int slices = lua_tointeger( L, -1 ); float height = lua_tonumber( L, -2 ); float radius = lua_tonumber( L, -3 ); - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshCone( radius, height, slices); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -875,14 +853,8 @@ int lmodelsGenMeshTorus( lua_State *L ) { int radSeg = lua_tointeger( L, -2 ); float size = lua_tonumber( L, -3 ); float radius = lua_tonumber( L, -4 ); - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshTorus( radius, size, radSeg, sides ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -908,14 +880,8 @@ int lmodelsGenMeshKnot( lua_State *L ) { int radSeg = lua_tointeger( L, -2 ); float size = lua_tonumber( L, -3 ); float radius = lua_tonumber( L, -4 ); - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshKnot( radius, size, radSeg, sides ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -945,16 +911,9 @@ int lmodelsGenMeshHeightmap( lua_State *L ) { lua_pushboolean( L, false ); return 1; } - Image *heightmap = state->images[ imageId ]; - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshHeightmap( *heightmap, size ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -963,100 +922,306 @@ int lmodelsGenMeshHeightmap( lua_State *L ) { } /* -> mesh = RL_GenMeshCustom( Vector3{} vertices, Vector2{} texCoords, Vector3{} normals ) +> mesh = RL_GenMeshCustom( Mesh{}, bool dynamic ) -Generate custom mesh +Generate custom mesh from vertex attribute data and uploads it into a VAO ( if supported ) and VBO - Failure return -1 - Success return int */ int lmodelsGenMeshCustom( lua_State *L ) { - if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) { - TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCustom( Vector3{} vertices, Vector2{} texCoords, Vector3{} normals )" ); + if ( !lua_istable( L, -2 ) || !lua_isboolean( L, -1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCustom( Mesh{}, bool dynamic )" ); lua_pushinteger( L, -1 ); return 1; } Mesh mesh = { 0 }; - size_t len = uluaGetTableLen( L ); - mesh.vertexCount = len * 3; - mesh.triangleCount = len; - - mesh.vertices = (float*)MemAlloc( mesh.vertexCount * 3 * sizeof(float) ); - mesh.texcoords = (float*)MemAlloc( mesh.vertexCount * 2 * sizeof(float) ); - mesh.normals = (float*)MemAlloc( mesh.vertexCount * 3 * sizeof(float) ); - mesh.colors = (unsigned char*)MemAlloc( mesh.vertexCount * 4 * sizeof(unsigned char) ); - - /* Normals. */ - - int t = lua_gettop( L ), i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - Vector3 vec = uluaGetVector3( L ); - mesh.normals[(i*3)+0] = vec.x; - mesh.normals[(i*3)+1] = vec.y; - mesh.normals[(i*3)+2] = vec.z; - } - i++; - lua_pop( L, 1 ); - } + bool dynamic = lua_toboolean( L, -1 ); lua_pop( L, 1 ); - /* TexCoords. */ - - t = lua_gettop( L ); - i = 0; - lua_pushnil( L ); + int t = lua_gettop( L ); + lua_pushnil( L ); while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - Vector2 vec = uluaGetVector2( L ); - mesh.texcoords[(i*2)+0] = vec.x; - mesh.texcoords[(i*2)+1] = vec.y; - } - i++; - lua_pop( L, 1 ); - } - lua_pop( L, 1 ); + if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); - /* Vertices. */ + mesh.vertexCount = len; + mesh.triangleCount = len / 3; + mesh.vertices = (float*)MemAlloc( len * 3 * sizeof(float) ); - t = lua_gettop( L ); - i = 0; - lua_pushnil( L ); + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); - while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - Vector3 vec = uluaGetVector3( L ); - mesh.vertices[(i*3)+0] = vec.x; - mesh.vertices[(i*3)+1] = vec.y; - mesh.vertices[(i*3)+2] = vec.z; + while ( lua_next( L, t2 ) != 0 ) { + Vector3 vec = uluaGetVector3( L ); - mesh.colors[(i*4)+0] = (unsigned char)255; - mesh.colors[(i*4)+1] = (unsigned char)255; - mesh.colors[(i*4)+2] = (unsigned char)255; - mesh.colors[(i*4)+3] = (unsigned char)255; - } - i++; - lua_pop( L, 1 ); - } - lua_pop( L, 1 ); - - UploadMesh( &mesh, false ); - - int j = 0; - - for ( j = 0; j < state->meshCount; j++ ) { - if ( state->meshes[j] == NULL ) { - break; + mesh.vertices[(i*3)+0] = vec.x; + mesh.vertices[(i*3)+1] = vec.y; + mesh.vertices[(i*3)+2] = vec.z; + i++; + lua_pop( L, 1 ); + } } + else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.texcoords = (float*)MemAlloc( len * 2 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector2 vec = uluaGetVector2( L ); + + mesh.texcoords[(i*2)+0] = vec.x; + mesh.texcoords[(i*2)+1] = vec.y; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.texcoords2 = (float*)MemAlloc( len * 2 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector2 vec = uluaGetVector2( L ); + + mesh.texcoords2[(i*2)+0] = vec.x; + mesh.texcoords2[(i*2)+1] = vec.y; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.normals = (float*)MemAlloc( len * 3 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector3 vec = uluaGetVector3( L ); + + mesh.normals[(i*3)+0] = vec.x; + mesh.normals[(i*3)+1] = vec.y; + mesh.normals[(i*3)+2] = vec.z; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.tangents = (float*)MemAlloc( len * 4 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector4 vec = uluaGetVector4( L ); + + mesh.tangents[(i*4)+0] = vec.x; + mesh.tangents[(i*4)+1] = vec.y; + mesh.tangents[(i*4)+2] = vec.z; + mesh.tangents[(i*4)+3] = vec.w; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.colors = (unsigned char*)MemAlloc( len * 4 * sizeof(unsigned char) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Color color = uluaGetColor( L ); + + mesh.colors[(i*4)+0] = color.r; + mesh.colors[(i*4)+1] = color.g; + mesh.colors[(i*4)+2] = color.b; + mesh.colors[(i*4)+3] = color.a; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.indices = (unsigned short*)MemAlloc( len * sizeof(unsigned short) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( 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 ); } - state->meshes[j] = malloc( sizeof( Mesh ) ); - *state->meshes[j] = mesh; - lua_pushinteger( L, j ); - checkMeshRealloc( j ); + UploadMesh( &mesh, dynamic ); + + int i = newMesh(); + + *state->meshes[i] = mesh; + lua_pushinteger( L, i ); + checkMeshRealloc( i ); + + return 1; +} + +/* +> success = RL_UpdateMesh( Mesh{} ) + +Update mesh vertex data in GPU. ( Mainly intented to be used with custom meshes ) + +- Failure return false +- Success return true +*/ +int lmodelsUpdateMesh( lua_State *L ) { + if ( !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UpdateMesh( Mesh{} )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t meshId = lua_tointeger( L, -1 ); + + if ( !validMesh( meshId ) ) { + lua_pushboolean( L, false ); + return 1; + } + Mesh *mesh = state->meshes[ meshId ]; + + int t = lua_gettop( L ); + 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 ); + 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 ); + 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 ); + Vector2 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector2( 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 ); + Vector2 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector2( 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 ); + Vector3 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector3( 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 ); + Vector4 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector4( 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 ); + Color data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetColor( 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 ); + 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 ); + } + lua_pushboolean( L, true ); return 1; }