diff options
author | sanine <sanine.not@pm.me> | 2023-02-22 01:02:45 -0600 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-02-22 01:02:45 -0600 |
commit | 353d60d3ebc353aef474633e7064067a2ef343ce (patch) | |
tree | d635c56573583070a416ff5dc4b33b18f82e909a /src | |
parent | 3cb9054bbb32e5ae14222bcef497680736dcce0e (diff) |
implement and demo basic obj loading
Diffstat (limited to 'src')
-rw-r--r-- | src/import/import.c | 193 |
1 files changed, 186 insertions, 7 deletions
diff --git a/src/import/import.c b/src/import/import.c index f860396..e2fc250 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -1,21 +1,200 @@ #include <lua.h> -#include <honeysuckle.h> +#include <lauxlib.h> +#include "util/util.h" #include "import.h" #define TINYOBJ_LOADER_C_IMPLEMENTATION #include <tinyobj/tinyobj_loader_c.h> -int dummy(lua_State *L) + +void read_file(void *ctx, const char *filename, int is_mtl, const char *obj_filename, char **buf, size_t *len) { - return 0; + FILE *f = fopen(filename, "rb"); + fseek(f, 0, SEEK_END); + *len = ftell(f); + fseek(f, 0, SEEK_SET); + + *buf = malloc(*len); + fread(*buf, *len, 1, f); + fclose(f); } -void setup_import(lua_State *L, int honey_tbl) +static void push_float_array(lua_State *L, float *arr, size_t len) +{ + lua_createtable(L, len, 0); + int tbl = lua_gettop(L); + for (int i=0; i<len; i++) { + lua_pushnumber(L, arr[i]); + lua_rawseti(L, tbl, i+1); + } +} + + +static void push_int_array(lua_State *L, int *arr, size_t len) { - hs_create_table(L, - hs_str_cfunc("dummy", dummy), + lua_createtable(L, len, 0); + int tbl = lua_gettop(L); + for (int i=0; i<len; i++) { + lua_pushinteger(L, arr[i]); + lua_rawseti(L, tbl, i+1); + } +} + + +static void push_material(lua_State *L, tinyobj_material_t mtl) +{ + lua_createtable(L, 0, 18); + int tbl = lua_gettop(L); + + lua_pushstring(L, mtl.name); + lua_setfield(L, tbl, "name"); + + push_float_array(L, mtl.ambient, 3); + lua_setfield(L, tbl, "ambient"); + push_float_array(L, mtl.diffuse, 3); + lua_setfield(L, tbl, "diffuse"); + push_float_array(L, mtl.specular, 3); + lua_setfield(L, tbl, "specular"); + push_float_array(L, mtl.transmittance, 3); + lua_setfield(L, tbl, "transmittance"); + push_float_array(L, mtl.emission, 3); + lua_setfield(L, tbl, "emission"); + lua_pushnumber(L, mtl.shininess); + lua_setfield(L, tbl, "shininess"); + lua_pushnumber(L, mtl.ior); + lua_setfield(L, tbl, "ior"); + lua_pushnumber(L, mtl.dissolve); + lua_setfield(L, tbl, "dissolve"); + + lua_pushinteger(L, mtl.illum); + lua_setfield(L, tbl, "illum"); + + lua_pushinteger(L, mtl.pad0); + lua_setfield(L, tbl, "pad0"); + + lua_pushstring(L, mtl.ambient_texname); + lua_setfield(L, tbl, "ambient_texname"); + lua_pushstring(L, mtl.diffuse_texname); + lua_setfield(L, tbl, "diffuse_texname"); + lua_pushstring(L, mtl.specular_texname); + lua_setfield(L, tbl, "specular_texname"); + lua_pushstring(L, mtl.specular_highlight_texname); + lua_setfield(L, tbl, "specular_highlight_texname"); + lua_pushstring(L, mtl.bump_texname); + lua_setfield(L, tbl, "bump_texname"); + lua_pushstring(L, mtl.displacement_texname); + lua_setfield(L, tbl, "displacement_texname"); + lua_pushstring(L, mtl.alpha_texname); + lua_setfield(L, tbl, "alpha_texname"); +} + + +int tinyobj_parse_obj_bind(lua_State *L) +{ + tinyobj_attrib_t attrib; + tinyobj_shape_t *shapes; + size_t num_shapes; + tinyobj_material_t *materials; + size_t num_materials; + + const char *file_name = luaL_checkstring(L, 1); + unsigned int flags = luaL_checkinteger(L, 2); + + int result = tinyobj_parse_obj( + &attrib, &shapes, &num_shapes, &materials, &num_materials, + file_name, read_file, L, flags ); - lua_setfield(L, honey_tbl, "import"); + if (result != TINYOBJ_SUCCESS) { + luaL_error(L, "failed to parse OBJ file \"%s\"", file_name); + } + + /* push attrib */ + lua_createtable(L, 0, 7); + int attrib_tbl = lua_gettop(L); + + /* push attrib.pad0 */ + lua_pushinteger(L, attrib.pad0); + lua_setfield(L, attrib_tbl, "pad0"); + + /* attrib.vertices */ + push_float_array(L, attrib.vertices, 3*attrib.num_vertices); + lua_setfield(L, attrib_tbl, "vertices"); + + /* attrib.normals */ + push_float_array(L, attrib.normals, 3*attrib.num_normals); + lua_setfield(L, attrib_tbl, "normals"); + + /* attrib.texcoords */ + push_float_array(L, attrib.texcoords, 3*attrib.num_texcoords); + lua_setfield(L, attrib_tbl, "texcoords"); + + /* attrib.faces */ + lua_createtable(L, attrib.num_faces, 0); + int face_array_tbl = lua_gettop(L); + for (int i=0; i<attrib.num_faces; i++) { + lua_createtable(L, 0, 3); + int face_tbl = lua_gettop(L); + /* push struct elements */ + lua_pushinteger(L, attrib.faces[i].v_idx); + lua_setfield(L, face_tbl, "v_idx"); + lua_pushinteger(L, attrib.faces[i].vt_idx); + lua_setfield(L, face_tbl, "vt_idx"); + lua_pushinteger(L, attrib.faces[i].vn_idx); + lua_setfield(L, face_tbl, "vn_idx"); + /* append table into array */ + lua_rawseti(L, face_array_tbl, i+1); + } + lua_setfield(L, attrib_tbl, "faces"); + + /* attrib.face_num_verts */ + push_int_array(L, attrib.face_num_verts, attrib.num_face_num_verts); + lua_setfield(L, attrib_tbl, "face_num_verts"); + + /* attrib.material_ids + * (we use the same len as face_num_verts because materials are per face) + */ + push_int_array(L, attrib.material_ids, attrib.num_face_num_verts); + lua_setfield(L, attrib_tbl, "material_ids"); + + /* shapes */ + lua_createtable(L, num_shapes, 0); + int shape_array_tbl = lua_gettop(L); + for (int i=0; i<num_shapes; i++) { + lua_createtable(L, 0, 3); + int shape_tbl = lua_gettop(L); + /* struct elements */ + lua_pushstring(L, shapes[i].name); + lua_setfield(L, shape_tbl, "name"); + lua_pushinteger(L, shapes[i].face_offset); + lua_setfield(L, shape_tbl, "face_offset"); + lua_pushinteger(L, shapes[i].length); + lua_setfield(L, shape_tbl, "length"); + /* append to array */ + lua_rawseti(L, shape_array_tbl, i+1); + } + + /* materials */ + lua_createtable(L, num_materials, 0); + int materials_array_tbl = lua_gettop(L); + for (int i=0; i<num_materials; i++) { + push_material(L, materials[i]); + lua_rawseti(L, materials_array_tbl, i+1); + } + + return 3; +} + + + +void setup_import(lua_State *L, int honey_tbl) +{ + struct honey_tbl_t tinyobj[] = { + H_FUNC("parse_obj", tinyobj_parse_obj_bind), + H_INT("FLAG_TRIANGULATE", TINYOBJ_FLAG_TRIANGULATE), + H_END, + }; + create_table(L, tinyobj); + lua_setfield(L, honey_tbl, "tinyobj"); } |