From d0eb5b0dcb589cfa74e801f19c911ae0f665eaa0 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Mon, 19 Feb 2024 17:22:28 -0800 Subject: Address TODO. --- game/src/plugins/texture_view.c | 4 +- game/src/plugins/viewer.c | 2 +- gfx/include/gfx/scene/object.h | 22 ++++----- gfx/src/asset/model.c | 16 +++--- gfx/src/renderer/renderer.c | 2 +- gfx/src/scene/object.c | 105 +++++++++++++++------------------------- gfx/src/scene/object_impl.h | 6 +-- gfx/src/util/skyquad.c | 3 +- 8 files changed, 66 insertions(+), 94 deletions(-) diff --git a/game/src/plugins/texture_view.c b/game/src/plugins/texture_view.c index b624f46..52dff57 100644 --- a/game/src/plugins/texture_view.c +++ b/game/src/plugins/texture_view.c @@ -73,11 +73,11 @@ bool init(Game* game, State** pp_state) { goto cleanup; } - SceneObject* object = gfx_make_object(); + SceneObject* object = + gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}}); if (!object) { goto cleanup; } - gfx_add_object_mesh(object, mesh); if (!(state->scene = gfx_make_scene())) { goto cleanup; diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c index 88821af..4f4ef03 100644 --- a/game/src/plugins/viewer.c +++ b/game/src/plugins/viewer.c @@ -195,7 +195,7 @@ static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { // pose). const mat4 model = gfx_get_node_global_transform(node); const SceneObject* obj = gfx_get_node_object(node); - const aabb3 box = gfx_calc_object_aabb(obj); + const aabb3 box = gfx_get_object_aabb(obj); gfx_imm_set_model_matrix(imm, &model); gfx_imm_draw_aabb3(imm, box); } diff --git a/gfx/include/gfx/scene/object.h b/gfx/include/gfx/scene/object.h index ccc9999..891c3cd 100644 --- a/gfx/include/gfx/scene/object.h +++ b/gfx/include/gfx/scene/object.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -10,8 +12,13 @@ typedef struct Skeleton Skeleton; typedef struct SceneObject SceneObject; +typedef struct ObjectDesc { + size_t num_meshes; + Mesh* meshes[GFX_MAX_NUM_MESHES]; +} ObjectDesc; + /// Create a new object. -SceneObject* gfx_make_object(); +SceneObject* gfx_make_object(const ObjectDesc*); /// Destroy the object. /// @@ -19,19 +26,10 @@ SceneObject* gfx_make_object(); /// node is destroyed. void gfx_destroy_object(SceneObject**); -/// Sets the object's transformation matrix. -void gfx_set_object_transform(SceneObject*, const mat4*); - -/// Add a mesh to the object. -void gfx_add_object_mesh(SceneObject*, Mesh*); - -/// Remove a mesh from the object. -void gfx_remove_object_mesh(SceneObject*, Mesh*); - /// Set the object's skeleton. void gfx_set_object_skeleton(SceneObject*, const Skeleton*); -/// Computes the object's bounding box. +/// Gets the object's bounding box. /// /// The object's bounding box is the bounding box of its mesh geometries. -aabb3 gfx_calc_object_aabb(const SceneObject*); +aabb3 gfx_get_object_aabb(const SceneObject*); diff --git a/gfx/src/asset/model.c b/gfx/src/asset/model.c index 05e6e91..37f129e 100644 --- a/gfx/src/asset/model.c +++ b/gfx/src/asset/model.c @@ -910,10 +910,7 @@ static bool load_meshes( for (cgltf_size m = 0; m < data->meshes_count; ++m) { const cgltf_mesh* mesh = &data->meshes[m]; - scene_objects[m] = gfx_make_object(); - if (!scene_objects[m]) { - return false; - } + ObjectDesc object_desc = {0}; for (cgltf_size p = 0; p < mesh->primitives_count; ++p) { assert(next_mesh < primitive_count); @@ -1173,11 +1170,18 @@ static bool load_meshes( return false; } - gfx_add_object_mesh(scene_objects[m], meshes[next_mesh]); + assert(object_desc.num_meshes < GFX_MAX_NUM_MESHES); + object_desc.meshes[object_desc.num_meshes] = meshes[next_mesh]; + object_desc.num_meshes++; ++next_mesh; } // glTF mesh primitive / gfx Mesh. - } // glTF mesh / gfx SceneObject. + + scene_objects[m] = gfx_make_object(&object_desc); + if (!scene_objects[m]) { + return false; + } + } // glTF mesh / gfx SceneObject. return true; } diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c index dbfc62b..161eed2 100644 --- a/gfx/src/renderer/renderer.c +++ b/gfx/src/renderer/renderer.c @@ -241,7 +241,7 @@ static void draw_recursively( // TODO: Avoid computing matrices like Modelview or MVP if the shader does // not use them. - const mat4 model_matrix = mat4_mul(node_transform, object->transform); + const mat4 model_matrix = node_transform; const mat4 modelview = mat4_mul(*state->view_matrix, model_matrix); const mat4 mvp = mat4_mul(*state->projection, modelview); diff --git a/gfx/src/scene/object.c b/gfx/src/scene/object.c index 68a1340..9291feb 100644 --- a/gfx/src/scene/object.c +++ b/gfx/src/scene/object.c @@ -8,66 +8,61 @@ #include -static void scene_object_make(SceneObject* object) { +static aabb3 calc_object_aabb(const SceneObject* object) { assert(object); - object->transform = mat4_id(); -} -SceneObject* gfx_make_object() { - SceneObject* object = mem_alloc_object(); - scene_object_make(object); - return object; -} + bool first = true; + aabb3 box; -void gfx_destroy_object(SceneObject** object) { - assert(object); - if (*object) { - if ((*object)->parent.val) { - gfx_del_node((*object)->parent); + mesh_link_idx ml = object->mesh_link; + while (ml.val) { + const MeshLink* mesh_link = mem_get_mesh_link(ml); + const mesh_idx mi = mesh_link->mesh; + if (mi.val) { + const Mesh* mesh = mem_get_mesh(mi); + const aabb3 mesh_box = gfx_get_geometry_aabb(mesh->geometry); + if (first) { + box = mesh_box; + first = false; + } else { + box = aabb3_sum(box, mesh_box); + } } - mem_free_object(object); + ml = mesh_link->next; } -} -void gfx_set_object_transform(SceneObject* object, const mat4* transform) { - assert(object); - assert(transform); - object->transform = *transform; + return box; } -void gfx_add_object_mesh(SceneObject* object, Mesh* mesh) { +static void add_object_mesh(SceneObject* object, Mesh* mesh) { assert(object); assert(mesh); - MeshLink* link = mem_alloc_mesh_link(); - assert(link); + MeshLink* link = mem_alloc_mesh_link(); link->mesh = mem_get_mesh_index(mesh); link->next = object->mesh_link; object->mesh_link = mem_get_mesh_link_index(link); } -void gfx_remove_object_mesh(SceneObject* object, Mesh* mesh) { - assert(object); - assert(mesh); +SceneObject* gfx_make_object(const ObjectDesc* desc) { + assert(desc); + + SceneObject* object = mem_alloc_object(); + for (size_t i = 0; i < desc->num_meshes; ++i) { + add_object_mesh(object, desc->meshes[i]); + } + object->box = calc_object_aabb(object); + return object; +} - MeshLink* prev = 0; - const mesh_idx mesh_index = mem_get_mesh_index(mesh); +void gfx_destroy_object(SceneObject** object) { + assert(object); - // Find the MeshLink in the object that contains the given mesh. - for (mesh_link_idx mesh_link_index = object->mesh_link; - mesh_link_index.val;) { - MeshLink* mesh_link = mem_get_mesh_link(mesh_link_index); - if (mesh_link->mesh.val == mesh_index.val) { - if (prev) { - prev->next = mesh_link->next; - } else { - object->mesh_link = mesh_link->next; - } - mem_free_mesh_link(&mesh_link); - break; + if (*object) { + if ((*object)->parent.val) { + gfx_del_node((*object)->parent); } - prev = mesh_link; - mesh_link_index = mesh_link->next; + mem_free_object(object); } } @@ -77,31 +72,7 @@ void gfx_set_object_skeleton(SceneObject* object, const Skeleton* skeleton) { object->skeleton = mem_get_skeleton_index(skeleton); } -// TODO: Could compute just once if we changed the Object API to require an -// object descriptor up front instead of allowing the client to add meshes -// and skeletons dynamically. -aabb3 gfx_calc_object_aabb(const SceneObject* object) { +aabb3 gfx_get_object_aabb(const SceneObject* object) { assert(object); - - bool first = true; - aabb3 box; - - mesh_link_idx ml = object->mesh_link; - while (ml.val) { - const MeshLink* mesh_link = mem_get_mesh_link(ml); - const mesh_idx mi = mesh_link->mesh; - if (mi.val) { - const Mesh* mesh = mem_get_mesh(mi); - const aabb3 mesh_box = gfx_get_geometry_aabb(mesh->geometry); - if (first) { - box = mesh_box; - first = false; - } else { - box = aabb3_sum(box, mesh_box); - } - } - ml = mesh_link->next; - } - - return box; + return object->box; } diff --git a/gfx/src/scene/object_impl.h b/gfx/src/scene/object_impl.h index 45119db..91e1427 100644 --- a/gfx/src/scene/object_impl.h +++ b/gfx/src/scene/object_impl.h @@ -19,8 +19,8 @@ typedef struct MeshLink { /// different for each SceneObject. Each SceneObject may then have a unique list /// of Meshes, and the Meshes are re-used. typedef struct SceneObject { - mat4 transform; - mesh_link_idx mesh_link; // First MeshLink in the list. + mesh_link_idx mesh_link; /// First MeshLink in the list. skeleton_idx skeleton; - node_idx parent; // Parent SceneNode. + node_idx parent; /// Parent SceneNode. + aabb3 box; } SceneObject; diff --git a/gfx/src/util/skyquad.c b/gfx/src/util/skyquad.c index d0f1cb0..5027705 100644 --- a/gfx/src/util/skyquad.c +++ b/gfx/src/util/skyquad.c @@ -56,11 +56,10 @@ SceneObject* gfx_make_skyquad( goto cleanup; } - object = gfx_make_object(); + object = gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}}); if (!object) { goto cleanup; } - gfx_add_object_mesh(object, mesh); return object; -- cgit v1.2.3