From 3d18eb99e66a127131f62a56fedacb8dffa61f83 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 25 Nov 2016 23:15:04 -0800 Subject: [PATCH] Refactor model loader; --- src/graphics/model.c | 33 ++++++++++++++++++++++-- src/graphics/model.h | 43 ++++++++++++++++++++++++++++++- src/headset/headset.h | 2 +- src/headset/vive.c | 3 ++- src/headset/vive.h | 2 +- src/loaders/model.c | 40 +++-------------------------- src/loaders/model.h | 51 +++---------------------------------- src/lovr/graphics.c | 8 ++---- src/lovr/types/controller.c | 2 +- 9 files changed, 87 insertions(+), 97 deletions(-) diff --git a/src/graphics/model.c b/src/graphics/model.c index 38b898db..1a0bf3a1 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -67,7 +67,6 @@ Model* lovrModelCreate(ModelData* modelData) { Model* model = lovrAlloc(sizeof(Model), lovrModelDestroy); if (!model) return NULL; - lovrRetain(&modelData->ref); model->modelData = modelData; vec_float_t vertices; @@ -114,11 +113,41 @@ void lovrModelDestroy(const Ref* ref) { if (model->texture) { lovrRelease(&model->texture->ref); } - lovrRelease(&model->modelData->ref); + lovrModelDataDestroy(model->modelData); lovrRelease(&model->buffer->ref); free(model); } +void lovrModelDataDestroy(ModelData* modelData) { + for (int i = 0; i < modelData->meshes.length; i++) { + ModelMesh* mesh = modelData->meshes.data[i]; + vec_deinit(&mesh->faces); + vec_deinit(&mesh->vertices); + vec_deinit(&mesh->normals); + if (modelData->hasTexCoords) { + vec_deinit(&mesh->texCoords); + } + free(mesh); + } + + vec_void_t nodes; + vec_init(&nodes); + vec_push(&nodes, modelData->root); + while (nodes.length > 0) { + ModelNode* node = vec_first(&nodes); + vec_extend(&nodes, &node->children); + mat4_deinit(node->transform); + vec_deinit(&node->meshes); + vec_deinit(&node->children); + vec_splice(&nodes, 0, 1); + free(node); + } + + vec_deinit(&modelData->meshes); + vec_deinit(&nodes); + free(modelData); +} + void lovrModelDraw(Model* model, float x, float y, float z, float size, float angle, float ax, float ay, float az) { lovrGraphicsPush(); lovrGraphicsTransform(x, y, z, size, size, size, angle, ax, ay, az); diff --git a/src/graphics/model.h b/src/graphics/model.h index 5315d9bb..a8894827 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -1,21 +1,62 @@ #include "graphics/buffer.h" #include "graphics/texture.h" -#include "loaders/model.h" +#include "matrix.h" #include "glfw.h" #include "util.h" +#include "vendor/vec/vec.h" #ifndef LOVR_MODEL_TYPES #define LOVR_MODEL_TYPES + +typedef struct { + float x; + float y; + float z; +} ModelVertex; + +typedef vec_t(ModelVertex) vec_model_vertex_t; + +typedef struct { + unsigned int indices[3]; +} ModelFace; + +typedef vec_t(ModelFace) vec_model_face_t; + +typedef struct { + vec_model_face_t faces; + vec_model_vertex_t vertices; + vec_model_vertex_t normals; + vec_model_vertex_t texCoords; +} ModelMesh; + +typedef vec_t(ModelMesh*) vec_model_mesh_t; + +typedef struct ModelNode { + mat4 transform; + vec_uint_t meshes; + vec_void_t children; +} ModelNode; + +typedef struct { + Ref ref; + ModelNode* root; + vec_model_mesh_t meshes; + int hasNormals; + int hasTexCoords; +} ModelData; + typedef struct { Ref ref; ModelData* modelData; Buffer* buffer; Texture* texture; } Model; + #endif Model* lovrModelCreate(ModelData* modelData); void lovrModelDestroy(const Ref* ref); +void lovrModelDataDestroy(ModelData* modelData); void lovrModelDraw(Model* model, float x, float y, float z, float scale, float angle, float ax, float ay, float az); Texture* lovrModelGetTexture(Model* model); void lovrModelSetTexture(Model* model, Texture* texture); diff --git a/src/headset/headset.h b/src/headset/headset.h index 6fd1e9d1..1fe6a865 100644 --- a/src/headset/headset.h +++ b/src/headset/headset.h @@ -1,4 +1,4 @@ -#include "loaders/model.h" +#include "graphics/model.h" #ifndef LOVR_HEADSET_TYPES #define LOVR_HEADSET_TYPES diff --git a/src/headset/vive.c b/src/headset/vive.c index 9d753bbf..8d3eab23 100644 --- a/src/headset/vive.c +++ b/src/headset/vive.c @@ -1,5 +1,6 @@ #include "headset/vive.h" #include "graphics/graphics.h" +#include "loaders/model.h" #include "util.h" #include #include @@ -436,7 +437,7 @@ ModelData* viveControllerNewModelData(void* headset, Controller* controller) { return NULL; } - ModelData* modelData = lovrModelDataCreateFromOpenVRModel(renderModel); + ModelData* modelData = lovrModelDataFromOpenVRModel(renderModel); state->vrRenderModels->FreeRenderModel(renderModel); return modelData; } diff --git a/src/headset/vive.h b/src/headset/vive.h index 72f37172..0ea13301 100644 --- a/src/headset/vive.h +++ b/src/headset/vive.h @@ -1,5 +1,5 @@ #include "headset/headset.h" -#include "loaders/model.h" +#include "graphics/model.h" #include "glfw.h" #include #ifndef _WIN32 diff --git a/src/loaders/model.c b/src/loaders/model.c index 27903b84..70bcfeff 100644 --- a/src/loaders/model.c +++ b/src/loaders/model.c @@ -24,8 +24,8 @@ static void assimpNodeTraversal(ModelNode* node, struct aiNode* assimpNode) { } } -ModelData* lovrModelDataCreateFromFile(void* data, int size) { - ModelData* modelData = lovrAlloc(sizeof(ModelData), lovrModelDataDestroy); +ModelData* lovrModelDataFromFile(void* data, int size) { + ModelData* modelData = malloc(sizeof(ModelData)); if (!modelData) return NULL; unsigned int flags = aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_OptimizeGraph | aiProcess_FlipUVs; @@ -100,8 +100,8 @@ ModelData* lovrModelDataCreateFromFile(void* data, int size) { return modelData; } -ModelData* lovrModelDataCreateFromOpenVRModel(RenderModel_t* renderModel) { - ModelData* modelData = lovrAlloc(sizeof(ModelData), lovrModelDataDestroy); +ModelData* lovrModelDataFromOpenVRModel(RenderModel_t* renderModel) { + ModelData* modelData = malloc(sizeof(ModelData)); if (!modelData) return NULL; ModelMesh* mesh = malloc(sizeof(ModelMesh)); @@ -154,35 +154,3 @@ ModelData* lovrModelDataCreateFromOpenVRModel(RenderModel_t* renderModel) { return modelData; } - -void lovrModelDataDestroy(const Ref* ref) { - ModelData* modelData = containerof(ref, ModelData); - - for (int i = 0; i < modelData->meshes.length; i++) { - ModelMesh* mesh = modelData->meshes.data[i]; - vec_deinit(&mesh->faces); - vec_deinit(&mesh->vertices); - vec_deinit(&mesh->normals); - if (modelData->hasTexCoords) { - vec_deinit(&mesh->texCoords); - } - free(mesh); - } - - vec_void_t nodes; - vec_init(&nodes); - vec_push(&nodes, modelData->root); - while (nodes.length > 0) { - ModelNode* node = vec_first(&nodes); - vec_extend(&nodes, &node->children); - mat4_deinit(node->transform); - vec_deinit(&node->meshes); - vec_deinit(&node->children); - vec_splice(&nodes, 0, 1); - free(node); - } - - vec_deinit(&modelData->meshes); - vec_deinit(&nodes); - free(modelData); -} diff --git a/src/loaders/model.h b/src/loaders/model.h index cc4f8f9d..c4bc073b 100644 --- a/src/loaders/model.h +++ b/src/loaders/model.h @@ -1,54 +1,9 @@ -#include "vendor/vec/vec.h" -#include "util.h" -#include "matrix.h" +#include "graphics/model.h" #include #ifndef _WIN32 #define __stdcall #endif #include -#ifndef LOVR_MODEL_DATA_TYPES -#define LOVR_MODEL_DATA_TYPES - -typedef struct { - float x; - float y; - float z; -} ModelVertex; - -typedef vec_t(ModelVertex) vec_model_vertex_t; - -typedef struct { - unsigned int indices[3]; -} ModelFace; - -typedef vec_t(ModelFace) vec_model_face_t; - -typedef struct { - vec_model_face_t faces; - vec_model_vertex_t vertices; - vec_model_vertex_t normals; - vec_model_vertex_t texCoords; -} ModelMesh; - -typedef vec_t(ModelMesh*) vec_model_mesh_t; - -typedef struct ModelNode { - mat4 transform; - vec_uint_t meshes; - vec_void_t children; -} ModelNode; - -typedef struct { - Ref ref; - ModelNode* root; - vec_model_mesh_t meshes; - int hasNormals; - int hasTexCoords; -} ModelData; - -#endif - -ModelData* lovrModelDataCreateFromFile(void* data, int size); -ModelData* lovrModelDataCreateFromOpenVRModel(RenderModel_t* renderModel); -void lovrModelDataDestroy(const Ref* ref); +ModelData* lovrModelDataFromFile(void* data, int size); +ModelData* lovrModelDataFromOpenVRModel(RenderModel_t* renderModel); diff --git a/src/lovr/graphics.c b/src/lovr/graphics.c index 9ee9d5e2..d7c4f426 100644 --- a/src/lovr/graphics.c +++ b/src/lovr/graphics.c @@ -5,6 +5,7 @@ #include "lovr/types/skybox.h" #include "lovr/types/texture.h" #include "graphics/graphics.h" +#include "loaders/model.h" #include "filesystem/filesystem.h" #include "util.h" #include @@ -567,7 +568,7 @@ int l_lovrGraphicsNewModel(lua_State* L) { if (!data) { return luaL_error(L, "Could not load model file '%s'", path); } else { - modelData = lovrModelDataCreateFromFile(data, size); + modelData = lovrModelDataFromFile(data, size); free(data); } } else { @@ -579,11 +580,6 @@ int l_lovrGraphicsNewModel(lua_State* L) { } luax_pushtype(L, Model, lovrModelCreate(modelData)); - - if (lua_isstring(L, 1)) { - lovrRelease(&modelData->ref); - } - return 1; } diff --git a/src/lovr/types/controller.c b/src/lovr/types/controller.c index b405759a..5089b169 100644 --- a/src/lovr/types/controller.c +++ b/src/lovr/types/controller.c @@ -1,6 +1,6 @@ #include "lovr/types/controller.h" #include "lovr/headset.h" -#include "loaders/model.h" +#include "graphics/model.h" #include "util.h" const luaL_Reg lovrController[] = {