From 0745aeb35bee22f52b812869cf77995ff1ba373b Mon Sep 17 00:00:00 2001
From: sanine <sanine.not@pm.me>
Date: Tue, 27 Sep 2022 00:10:42 -0500
Subject: implement scene loading

---
 src/import/import.c            | 54 ++++++++++++++++++++++++++-------------
 src/import/import_mesh.test.c  | 10 ++++----
 src/import/import_scene.test.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+), 22 deletions(-)

diff --git a/src/import/import.c b/src/import/import.c
index 8852c81..306601e 100644
--- a/src/import/import.c
+++ b/src/import/import.c
@@ -33,6 +33,8 @@ static void push_aistring(lua_State *L, struct aiString str)
 }
 
 
+#ifndef TEST_IMPORT_SCENE
+
 /* mesh components:
  * DONE:
  * mBitangents
@@ -57,13 +59,13 @@ static void push_aistring(lua_State *L, struct aiString str)
  * mPrimitiveTypes
  * mTextureCoordsNames
  */
-static void push_mesh(lua_State *L, struct aiMesh mesh)
+static void push_mesh(lua_State *L, struct aiMesh *mesh)
 {
 	/* --=== create mesh table ===-- */
 	lua_createtable(L, 0, 1);
 	int meshtbl = lua_gettop(L);
 
-	int count = mesh.mNumVertices;
+	int count = mesh->mNumVertices;
 	int pop_count = 0;
 
 	/* --=== create tables ===-- */
@@ -75,7 +77,7 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 
 	/* normals */
 	int normals = 0;
-	if (mesh.mNormals != NULL) {
+	if (mesh->mNormals != NULL) {
 		lua_createtable(L, count, 0);
 		normals = lua_gettop(L);
 		pop_count += 1;
@@ -84,7 +86,7 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 	/* tangents & bitangents */
 	int tangents = 0;
 	int bitangents = 0;
-	if (mesh.mTangents != NULL) {
+	if (mesh->mTangents != NULL) {
 		lua_createtable(L, count, 0);
 		tangents = lua_gettop(L);
 		lua_createtable(L, count, 0);
@@ -97,7 +99,7 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 	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 (mesh->mTextureCoords[i] != NULL) {
 			if (!uvs) {
 				/* ensure uv table is created */
 				lua_createtable(L, 1, 0);
@@ -114,7 +116,7 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 			lua_pushvalue(L, uv_channels[i]);
 			lua_rawseti(L, uvs, i+1);
 			/* store dimensionality */
-			lua_pushinteger(L, mesh.mNumUVComponents[i]);
+			lua_pushinteger(L, mesh->mNumUVComponents[i]);
 			lua_rawseti(L, uv_components, i+1);
 		}
 	}
@@ -123,20 +125,20 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 
 	for (int i=0; i<count; i++) {
 		/* positions */
-		push_vector(L, mesh.mVertices[i]);
+		push_vector(L, mesh->mVertices[i]);
 		lua_rawseti(L, vertices, i+1);
 
 		/* normals */
 		if (normals) {
-			push_vector(L, mesh.mNormals[i]);
+			push_vector(L, mesh->mNormals[i]);
 			lua_rawseti(L, normals, i+1);
 		}
 
 		/* tangents */
 		if (tangents) {
-			push_vector(L, mesh.mTangents[i]);
+			push_vector(L, mesh->mTangents[i]);
 			lua_rawseti(L, tangents, i+1);
-			push_vector(L, mesh.mBitangents[i]);
+			push_vector(L, mesh->mBitangents[i]);
 			lua_rawseti(L, bitangents, i+1);
 		}
 
@@ -144,7 +146,7 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 		if (uvs) {
 			for (int j=0; j<AI_MAX_NUMBER_OF_TEXTURECOORDS; j++) {
 				if (uv_channels[j]) {
-					push_vector(L, mesh.mTextureCoords[j][i]);
+					push_vector(L, mesh->mTextureCoords[j][i]);
 					lua_rawseti(L, uv_channels[j], i+1);
 				}
 			}
@@ -154,12 +156,12 @@ static void push_mesh(lua_State *L, struct aiMesh mesh)
 	/* --=== populate faces ===-- */
 
 	int faces = 0;
-	if (mesh.mNumFaces != 0) {
-		lua_createtable(L, mesh.mNumFaces, 0);
+	if (mesh->mNumFaces != 0) {
+		lua_createtable(L, mesh->mNumFaces, 0);
 		faces = lua_gettop(L);
 		pop_count += 1;
-		for (int i=0; i<mesh.mNumFaces; i++) {
-			push_face(L, mesh.mFaces[i]);
+		for (int i=0; i<mesh->mNumFaces; i++) {
+			push_face(L, mesh->mFaces[i]);
 			lua_rawseti(L, faces, i+1);
 		}
 	}
@@ -226,8 +228,26 @@ static void push_node(lua_State *L, struct aiNode *node)
 	}
 }
 
+#endif
+
 
-static void push_scene(lua_State *L, struct aiNode *node)
+static void push_scene(lua_State *L, struct aiScene *scene)
 {
-	
+	/* meshes */
+	lua_createtable(L, scene->mNumMeshes, 0);
+	int meshtbl = lua_gettop(L);
+	for (int i=0; i<scene->mNumMeshes; i++) {
+		push_mesh(L, scene->mMeshes[i]);
+		lua_rawseti(L, meshtbl, i+1);
+	}
+
+	/* nodes */
+	push_node(L, scene->mRootNode);
+	int nodetbl = lua_gettop(L);
+
+	/* scene */
+	hs_create_table(L,
+		hs_str_tbl("rootNode", nodetbl),
+		hs_str_tbl("meshes", meshtbl),
+	);
 }
diff --git a/src/import/import_mesh.test.c b/src/import/import_mesh.test.c
index 07400fd..fdbfbf0 100644
--- a/src/import/import_mesh.test.c
+++ b/src/import/import_mesh.test.c
@@ -152,7 +152,7 @@ void test_push_mesh()
 
 	/* push */	
 	int top_before = lua_gettop(L);
-	push_mesh(L, mesh);
+	push_mesh(L, &mesh);
 	int meshtbl = lua_gettop(L);
 
 	/* check output */
@@ -186,7 +186,7 @@ void test_push_mesh_faces()
 
 	/* push */	
 	int top_before = lua_gettop(L);
-	push_mesh(L, mesh);
+	push_mesh(L, &mesh);
 	int meshtbl = lua_gettop(L);
 
 	/* check output */
@@ -220,7 +220,7 @@ void test_push_mesh_normals()
 
 	/* push */	
 	int top_before = lua_gettop(L);
-	push_mesh(L, mesh);
+	push_mesh(L, &mesh);
 	int meshtbl = lua_gettop(L);
 
 	/* check output */
@@ -254,7 +254,7 @@ void test_push_mesh_tangents()
 
 	/* push */	
 	int top_before = lua_gettop(L);
-	push_mesh(L, mesh);
+	push_mesh(L, &mesh);
 	int meshtbl = lua_gettop(L);
 
 	/* check output */
@@ -289,7 +289,7 @@ void test_push_mesh_uvs()
 
 	/* push */	
 	int top_before = lua_gettop(L);
-	push_mesh(L, mesh);
+	push_mesh(L, &mesh);
 	int meshtbl = lua_gettop(L);
 
 	/* check output */
diff --git a/src/import/import_scene.test.c b/src/import/import_scene.test.c
index 72718eb..3530f0b 100644
--- a/src/import/import_scene.test.c
+++ b/src/import/import_scene.test.c
@@ -5,9 +5,66 @@
 #include "import.test.h"
 
 
+void mock_push_mesh(lua_State *L, struct aiMesh *mesh)
+{
+	lua_pushlightuserdata(L, mesh);
+}
+
+void mock_push_node(lua_State *L, struct aiNode *node)
+{
+	lua_pushlightuserdata(L, node);
+}
+
+#define TEST_IMPORT_SCENE
+
+#define push_mesh mock_push_mesh
+#define push_node mock_push_node
 #include "import.c"
+#undef push_mesh
+#undef push_node
 
 
 void test_push_scene()
 {
+	lua_State *L = luaL_newstate();
+
+	struct aiScene scene;
+	const int num_meshes = 8;
+	struct aiMesh m[num_meshes];
+	struct aiMesh *meshes[num_meshes];
+	for (int i=0; i<num_meshes; i++) {
+		meshes[i] = m + i;
+	}
+	
+	scene.mMeshes = meshes;
+	scene.mNumMeshes = num_meshes;
+
+	struct aiNode root;
+	scene.mRootNode = &root;
+
+	/* push */
+	int top = lua_gettop(L);
+	push_scene(L, &scene);
+
+	lily_assert_int_equal(lua_gettop(L) - top, 1);
+	lily_assert_int_equal(lua_type(L, -1), LUA_TTABLE);
+	int scenetbl = lua_gettop(L);
+
+	lua_getfield(L, scenetbl, "meshes");
+	lily_assert_int_equal(lua_objlen(L, -1), num_meshes);
+	int meshtbl = lua_gettop(L);
+
+	for (int i=0; i<num_meshes; i++) {
+		lua_rawgeti(L, meshtbl, i+1);
+		lily_assert_ptr_equal(lua_touserdata(L, -1), m+i);
+		lua_pop(L, 1);
+	}
+	lua_pop(L, 1);
+
+	lua_getfield(L, scenetbl, "rootNode");
+	lily_assert_int_equal(lua_type(L, -1), LUA_TLIGHTUSERDATA);
+	lily_assert_ptr_equal(lua_touserdata(L, -1), &root);
+	lua_pop(L, 2);
+
+	lua_close(L);
 }
-- 
cgit v1.2.1