From c3698446644365283fcd3d3f47f3eea67cad8331 Mon Sep 17 00:00:00 2001 From: sanine-a Date: Tue, 27 Oct 2020 20:58:46 -0500 Subject: fix bug with working directory and add Vector and Matrix wrappers --- src/cglm_bindings.c | 17 ++++++- src/cglm_bindings.h | 12 +++++ src/honey.c | 14 ++---- src/mesh/mesh.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/mesh/mesh.h | 8 ++++ 5 files changed, 165 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/cglm_bindings.c b/src/cglm_bindings.c index 95c9d81..f8f6c8a 100644 --- a/src/cglm_bindings.c +++ b/src/cglm_bindings.c @@ -61,6 +61,7 @@ void honey_setup_cglm(lua_State* L) honey_lua_element camera_elements[] = { { "perspective", HONEY_FUNCTION, { .function = honey_cglm_perspective } }, { "orthographic", HONEY_FUNCTION, { .function = honey_cglm_orthographic } }, + { "look", HONEY_FUNCTION, { .function = honey_cglm_look } }, }; honey_lua_element cglm_elements[] = { @@ -73,7 +74,7 @@ void honey_setup_cglm(lua_State* L) { "mat3", HONEY_TABLE, { .table = { 8, mat3_elements } } }, { "mat4", HONEY_TABLE, { .table = { 10, mat4_elements } } }, { "affine", HONEY_TABLE, { .table = { 3, affine_elements } } }, - { "camera", HONEY_TABLE, { .table = { 2, camera_elements } } }, + { "camera", HONEY_TABLE, { .table = { 3, camera_elements } } }, }; honey_lua_create_table(L, cglm_elements, 9); @@ -769,3 +770,17 @@ int honey_cglm_orthographic(lua_State* L) glm_ortho_aabb(box, matrix); return 0; } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cglm_look(lua_State* L) +{ + float *position, *direction, *up, *dest; + honey_lua_parse_arguments(L, 4, + HONEY_USERDATA, &position, + HONEY_USERDATA, &direction, + HONEY_USERDATA, &up, + HONEY_USERDATA, &dest); + glm_look(position, direction, up, dest); + return 0; +} diff --git a/src/cglm_bindings.h b/src/cglm_bindings.h index 09a29c3..ba7714e 100644 --- a/src/cglm_bindings.h +++ b/src/cglm_bindings.h @@ -508,4 +508,16 @@ int honey_cglm_perspective(lua_State* L); */ int honey_cglm_orthographic(lua_State* L); +/** @brief Compute the view matrix. + * + * @param[in] position The camera's vec3 position. + * @param[in] direction The vec3 direction the camera is facing. + * @param[in] up The camera's vec3 up vector. + * @param[out] dest The view matrix destination. + * + * @returns Nothing. + */ +int honey_cglm_look(lua_State* L); + + #endif diff --git a/src/honey.c b/src/honey.c index 17b0648..c63ab2f 100644 --- a/src/honey.c +++ b/src/honey.c @@ -97,16 +97,9 @@ bool honey_run(lua_State* L, honey_options opts) { honey_window_information* info = lua_touserdata(L, -1); honey_window window = info->window; - char* script; - honey_result res = honey_format_string(&script, - "%s/main.lua", - opts.script_directory); - if (res != HONEY_OK) { - fprintf(stderr, "[honey] FATAL: could not allocate space for script filename!"); - return false; - } + chdir(opts.script_directory); - if (luaL_loadfile(L, script) == 0) { + if (luaL_loadfile(L, "main.lua") == 0) { if (!honey_lua_pcall(L, 0, 1) == 0) { const char* error = lua_tostring(L, -1); fprintf(stderr, "[honey] ERROR: %s\n", error); @@ -116,8 +109,7 @@ bool honey_run(lua_State* L, honey_options opts) { else { fprintf(stderr, - "[honey] ERROR: failed to load %s: %s!\n", - script, + "[honey] ERROR: failed to load main.lua: %s!\n", lua_tostring(L, -1)); return false; } diff --git a/src/mesh/mesh.c b/src/mesh/mesh.c index 9c045ec..ab3e92c 100644 --- a/src/mesh/mesh.c +++ b/src/mesh/mesh.c @@ -22,6 +22,7 @@ static int honey_mesh_lua_delete(lua_State* L) void honey_setup_mesh(lua_State* L) { honey_lua_element mesh_elements[] = { + { "load", HONEY_FUNCTION, { .function = honey_mesh_load } }, { "draw", HONEY_FUNCTION, { .function = honey_mesh_lua_draw } }, { "delete", HONEY_FUNCTION, { .function = honey_mesh_lua_delete } }, }; @@ -31,6 +32,131 @@ void honey_setup_mesh(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +static honey_mesh assimp_to_honey_mesh(struct aiMesh* mesh, + struct aiScene* scene) +{ + unsigned int vertex_step = 6; + bool mesh_has_uvs = false; + unsigned int n_vertices = mesh->mNumVertices; + + if (mesh->mTextureCoords[0]) { + mesh_has_uvs = true; + vertex_step = 8; + } + + float* vertices = malloc(sizeof(float) * vertex_step * n_vertices); + for (int i=0; imVertices[i].x; + vertices[j+1] = mesh->mVertices[i].y; + vertices[j+2] = mesh->mVertices[i].z; + + /* normals */ + vertices[j+3] = mesh->mNormals[i].x; + vertices[j+4] = mesh->mNormals[i].y; + vertices[j+5] = mesh->mNormals[i].z; + + /* uvs? */ + if (mesh_has_uvs) { + vertices[j+6] = mesh->mTextureCoords[0][i].x; + vertices[j+7] = mesh->mTextureCoords[0][i].y; + } + } + + unsigned int n_indices = mesh->mNumFaces*3; + unsigned int* indices = malloc(sizeof(unsigned int) * n_indices); + for (int i=0; imNumFaces; i++) { + int j = 3*i; + struct aiFace face = mesh->mFaces[i]; + indices[j+0] = face.mIndices[0]; + indices[j+1] = face.mIndices[1]; + indices[j+2] = face.mIndices[2]; + } + + honey_mesh result; + + if (mesh_has_uvs) { + unsigned int n_attributes = 3; + unsigned int attribute_sizes[] = { 3, 3, 2 }; + honey_mesh_new(&result, + vertices, n_vertices, + n_attributes, attribute_sizes, + indices, n_indices); + } + else { + unsigned int n_attributes = 2; + unsigned int attribute_sizes[] = { 3, 3 }; + honey_mesh_new(&result, + vertices, n_vertices, + n_attributes, attribute_sizes, + indices, n_indices); + } + + free(vertices); + free(indices); + + return result; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static void process_nodes_recursively(lua_State* L, + struct aiScene* scene, + struct aiNode* node, + int* n_meshes) +{ + for (int i=0; imNumMeshes; i++) { + honey_mesh* mesh = lua_newuserdata(L, sizeof(honey_mesh)); + struct aiMesh* assimp_mesh = scene->mMeshes[node->mMeshes[i]]; + *mesh = assimp_to_honey_mesh(assimp_mesh, scene); + lua_rawseti(L, -2, *n_meshes); + *n_meshes++; + } + + for (int i=0; imNumChildren; i++) { + process_nodes_recursively(L, scene, node->mChildren[i], n_meshes); + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_mesh_load(lua_State* L) +{ + char* filename; + honey_lua_parse_arguments(L, 1, HONEY_STRING, &filename); + + int n_meshes = 1; + + struct aiScene* scene = aiImportFile(filename, + aiProcess_Triangulate | + aiProcess_FlipUVs); + if (scene == NULL) { + char* error; + honey_format_string(&error, "could not open file '%s'", filename); + lua_pushstring(L, error); + free(error); + lua_error(L); + } + + if (scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || + scene->mRootNode == NULL) { + char* error; + honey_format_string(&error, "could not read mesh(es) in '%s'", filename); + lua_pushstring(L, error); + free(error); + lua_error(L); + } + + lua_createtable(L, 0, 0); + + process_nodes_recursively(L, scene, scene->mRootNode, n_meshes); + + return 1; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + honey_result honey_mesh_new(honey_mesh* mesh, float* vertices, unsigned int n_vertices, diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h index 81bcc94..0f9c1a3 100644 --- a/src/mesh/mesh.h +++ b/src/mesh/mesh.h @@ -16,6 +16,14 @@ typedef struct { /** @brief Lua bindings for mesh drawing and deletion functions. */ void honey_setup_mesh(lua_State* L); +/** @brief Load all meshes from a file. + * + * @param[in] filename The name of the file to load from. + * + * @returns A table containing all of the meshes. + */ +int honey_mesh_load(lua_State* L); + /** @brief Create a new mesh from vertex and index arrays. * * Note that this function creates copies of the vertex and index arrays, -- cgit v1.2.1