diff options
-rw-r--r-- | src/import/import.c | 48 | ||||
-rw-r--r-- | src/import/import.test.c | 138 |
2 files changed, 184 insertions, 2 deletions
diff --git a/src/import/import.c b/src/import/import.c index 73075d4..d58de0f 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -42,6 +42,8 @@ void push_aistring(lua_State *L, struct aiString str) * mNumVertices * mTangents * mVertices + * mNumUVComponents + * mTextureCoords * * TODO: * mAnimMeshes @@ -52,9 +54,7 @@ void push_aistring(lua_State *L, struct aiString str) * mName * mNumAnimMeshes * mNumBones - * mNumUVComponents * mPrimitiveTypes - * mTextureCoords * mTextureCoordsNames */ void push_mesh(lua_State *L, struct aiMesh mesh) @@ -92,6 +92,33 @@ void push_mesh(lua_State *L, struct aiMesh mesh) pop_count += 2; } + /* uvs */ + int uvs = 0; + int uv_components = 0; + int uv_channels[AI_MAX_NUMBER_OF_TEXTURECOORDS]; + for (int i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) { + if (mesh.mTextureCoords[i] != NULL) { + if (!uvs) { + /* ensure uv table is created */ + lua_createtable(L, 1, 0); + uvs = lua_gettop(L); + lua_createtable(L, 1, 0); + uv_components = lua_gettop(L); + pop_count += 2; + } + lua_createtable(L, count, 0); + uv_channels[i] = lua_gettop(L); + pop_count += 1; + + /* store table in uvs */ + lua_pushvalue(L, uv_channels[i]); + lua_rawseti(L, uvs, i+1); + /* store dimensionality */ + lua_pushinteger(L, mesh.mNumUVComponents[i]); + lua_rawseti(L, uv_components, i+1); + } + } + /* --=== populate vertices ===-- */ for (int i=0; i<count; i++) { @@ -112,6 +139,16 @@ void push_mesh(lua_State *L, struct aiMesh mesh) push_vector(L, mesh.mBitangents[i]); lua_rawseti(L, bitangents, i+1); } + + /* uvs */ + if (uvs) { + for (int j=0; j<AI_MAX_NUMBER_OF_TEXTURECOORDS; j++) { + if (uv_channels[j]) { + push_vector(L, mesh.mTextureCoords[j][i]); + lua_rawseti(L, uv_channels[j], i+1); + } + } + } } /* --=== populate faces ===-- */ @@ -149,6 +186,13 @@ void push_mesh(lua_State *L, struct aiMesh mesh) lua_setfield(L, meshtbl, "faces"); } + if (uvs) { + lua_pushvalue(L, uvs); + lua_setfield(L, meshtbl, "uvs"); + lua_pushvalue(L, uv_components); + lua_setfield(L, meshtbl, "numUvComponents"); + } + /* --=== clean up ===-- */ lua_pop(L, pop_count); } diff --git a/src/import/import.test.c b/src/import/import.test.c index e17a685..bd15205 100644 --- a/src/import/import.test.c +++ b/src/import/import.test.c @@ -101,6 +101,9 @@ void test_normals(lua_State *L, int meshtbl); void create_tangents(struct aiMesh *mesh); void test_tangents(lua_State *L, int meshtbl); +void create_uvs(struct aiMesh *mesh); +void test_uvs(lua_State *L, int meshtbl); + void test_nil(lua_State *L, int meshtbl, const char *field); @@ -117,6 +120,9 @@ void test_nil(lua_State *L, int meshtbl, const char *field); struct aiVector3D bitangents[NUM_MESH_VERTICES]; \ mesh.mTangents = tangents; \ mesh.mBitangents = bitangents; \ + struct aiVector3D uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS * NUM_MESH_VERTICES]; \ + for (int i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) \ + mesh.mTextureCoords[i] = uvs + (i*NUM_MESH_VERTICES); \ struct aiFace faces[NUM_MESH_FACES]; \ unsigned int index_array[3*NUM_MESH_FACES]; \ for (int i=0; i<NUM_MESH_FACES; i++) \ @@ -137,6 +143,8 @@ void test_push_mesh() mesh.mNormals = NULL; mesh.mTangents = NULL; mesh.mBitangents = NULL; + for (int i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) + mesh.mTextureCoords[i] = NULL; /* setup mesh */ create_vertices(&mesh); @@ -168,6 +176,8 @@ void test_push_mesh_faces() mesh.mNormals = NULL; mesh.mTangents = NULL; mesh.mBitangents = NULL; + for (int i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) + mesh.mTextureCoords[i] = NULL; /* setup mesh */ create_vertices(&mesh); @@ -199,6 +209,8 @@ void test_push_mesh_normals() ALLOCATE_MEMORY(); mesh.mTangents = NULL; mesh.mBitangents = NULL; + for (int i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) + mesh.mTextureCoords[i] = NULL; /* setup mesh */ create_vertices(&mesh); @@ -230,6 +242,8 @@ void test_push_mesh_tangents() /* allocate memory */ ALLOCATE_MEMORY(); + for (int i=0; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) + mesh.mTextureCoords[i] = NULL; /* setup mesh */ create_vertices(&mesh); @@ -255,6 +269,42 @@ void test_push_mesh_tangents() } +void test_push_mesh_uvs() +{ + lua_State *L = luaL_newstate(); + struct aiMesh mesh; + mesh.mNumVertices = NUM_MESH_VERTICES; + mesh.mNumFaces = NUM_MESH_FACES; + + /* allocate memory */ + ALLOCATE_MEMORY(); + + /* setup mesh */ + create_vertices(&mesh); + create_faces(&mesh); + create_normals(&mesh); + create_tangents(&mesh); + create_uvs(&mesh); + + /* push */ + int top_before = lua_gettop(L); + push_mesh(L, mesh); + int meshtbl = lua_gettop(L); + + /* check output */ + lily_assert_int_equal(lua_type(L, meshtbl), LUA_TTABLE); + lily_assert_int_equal(meshtbl - top_before, 1); /* make sure we cleaned up correctly */ + test_vertices(L, meshtbl); + test_faces(L, meshtbl); + test_normals(L, meshtbl); + test_tangents(L, meshtbl); + test_uvs(L, meshtbl); + + lua_close(L); + +} + + void create_vertices(struct aiMesh *mesh) { mesh->mVertices[0] = (struct aiVector3D) { 0, 0, 0 }; @@ -420,6 +470,93 @@ void test_tangents(lua_State *L, int meshtbl) } +void create_uvs(struct aiMesh *mesh) +{ + mesh->mNumUVComponents[0] = 2; + mesh->mTextureCoords[0][0] = (struct aiVector3D) { 0, 0, 0 }; + mesh->mTextureCoords[0][1] = (struct aiVector3D) { 0, 1, 0 }; + mesh->mTextureCoords[0][2] = (struct aiVector3D) { 1, 0, 0 }; + mesh->mTextureCoords[0][3] = (struct aiVector3D) { 1, 1, 0 }; + + mesh->mNumUVComponents[1] = 1; + mesh->mTextureCoords[1][0] = (struct aiVector3D) { 0.0, 0, 0 }; + mesh->mTextureCoords[1][1] = (struct aiVector3D) { 0.2, 0, 0 }; + mesh->mTextureCoords[1][2] = (struct aiVector3D) { 0.4, 0, 0 }; + mesh->mTextureCoords[1][3] = (struct aiVector3D) { 0.8, 0, 0 }; + + for (int i=2; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) + mesh->mTextureCoords[i] = NULL; +} + + +static int check_uv(lua_State *L, int meshtbl, int channel, int index, + float x, float y, float z) +{ + lua_getfield(L, meshtbl, "uvs"); + lily_assert(lua_type(L, -1) == LUA_TTABLE, "field 'uvs' is not a table!"); + lua_rawgeti(L, -1, channel); + lily_assert(lua_type(L, -1) == LUA_TTABLE, "uvs[%d] is not a table!", channel); + lua_rawgeti(L, -1, index); + lily_assert(lua_type(L, -1) == LUA_TTABLE, "uvs[%d][%d] is not a table!", channel, index); + + lua_getfield(L, -1, "x"); + lily_assert(lua_type(L, -1) == LUA_TNUMBER, "uvs[%d][%d].x is not a number!", channel, index); + float vx = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "y"); + lily_assert(lua_type(L, -1) == LUA_TNUMBER, "uvs[%d][%d].y is not a number!", channel, index); + float vy = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_getfield(L, -1, "z"); + lily_assert(lua_type(L, -1) == LUA_TNUMBER, "uvs[%d][%d].z is not a number!", channel, index); + float vz = lua_tonumber(L, -1); + lua_pop(L, 1); + + lua_pop(L, 3); + lily_assert( + (fabs(vx - x) < 0.1) && + (fabs(vy - y) < 0.1) && + (fabs(vz - z) < 0.1), + "uvs[%d][%d] is [%f, %f, %f], but expected [%f, %f, %f]!", + channel, index, + vx, vy, vz, + x, y, z + ); +} + + +void test_uvs(lua_State *L, int meshtbl) +{ + lua_getfield(L, meshtbl, "numUvComponents"); + lily_assert(lua_type(L, -1) == LUA_TTABLE, "field 'numUvComponents' is not a table!"); + lua_rawgeti(L, -1, 1); + lily_assert_int_equal(lua_tointeger(L, -1), 2); + lua_pop(L, 1); + lua_rawgeti(L, -1, 2); + lily_assert_int_equal(lua_tointeger(L, -1), 1); + lua_pop(L, 1); + + check_uv(L, meshtbl, 1, 1, 0, 0, 0); + check_uv(L, meshtbl, 1, 2, 0, 1, 0); + check_uv(L, meshtbl, 1, 3, 1, 0, 0); + check_uv(L, meshtbl, 1, 4, 1, 1, 0); + + check_uv(L, meshtbl, 2, 1, 0.0, 0, 0); + check_uv(L, meshtbl, 2, 2, 0.2, 0, 0); + check_uv(L, meshtbl, 2, 3, 0.4, 0, 0); + check_uv(L, meshtbl, 2, 4, 0.8, 0, 0); + + lua_getfield(L, meshtbl, "uvs"); + int uvtbl = lua_gettop(L); + for (int i=2; i<AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) { + lua_rawgeti(L, uvtbl, i+1); + lily_assert(lua_type(L, -1) == LUA_TNIL, "uv channel %d is non-nil!", i+1); + lua_pop(L, 1); + } + lua_pop(L, 1); +} void test_nil(lua_State *L, int meshtbl, const char *field) { @@ -442,4 +579,5 @@ void suite_import() lily_run_test(test_push_mesh_faces); lily_run_test(test_push_mesh_normals); lily_run_test(test_push_mesh_tangents); + lily_run_test(test_push_mesh_uvs); } |