summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/src/plugins/texture_view.c4
-rw-r--r--game/src/plugins/viewer.c2
-rw-r--r--gfx/include/gfx/scene/object.h22
-rw-r--r--gfx/src/asset/model.c16
-rw-r--r--gfx/src/renderer/renderer.c2
-rw-r--r--gfx/src/scene/object.c105
-rw-r--r--gfx/src/scene/object_impl.h6
-rw-r--r--gfx/src/util/skyquad.c3
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) {
73 goto cleanup; 73 goto cleanup;
74 } 74 }
75 75
76 SceneObject* object = gfx_make_object(); 76 SceneObject* object =
77 gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}});
77 if (!object) { 78 if (!object) {
78 goto cleanup; 79 goto cleanup;
79 } 80 }
80 gfx_add_object_mesh(object, mesh);
81 81
82 if (!(state->scene = gfx_make_scene())) { 82 if (!(state->scene = gfx_make_scene())) {
83 goto cleanup; 83 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) {
195 // pose). 195 // pose).
196 const mat4 model = gfx_get_node_global_transform(node); 196 const mat4 model = gfx_get_node_global_transform(node);
197 const SceneObject* obj = gfx_get_node_object(node); 197 const SceneObject* obj = gfx_get_node_object(node);
198 const aabb3 box = gfx_calc_object_aabb(obj); 198 const aabb3 box = gfx_get_object_aabb(obj);
199 gfx_imm_set_model_matrix(imm, &model); 199 gfx_imm_set_model_matrix(imm, &model);
200 gfx_imm_draw_aabb3(imm, box); 200 gfx_imm_draw_aabb3(imm, box);
201 } 201 }
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 @@
1#pragma once 1#pragma once
2 2
3#include <gfx/sizes.h>
4
3#include <math/fwd.h> 5#include <math/fwd.h>
4 6
5#include <math/aabb3.h> 7#include <math/aabb3.h>
@@ -10,8 +12,13 @@ typedef struct Skeleton Skeleton;
10 12
11typedef struct SceneObject SceneObject; 13typedef struct SceneObject SceneObject;
12 14
15typedef struct ObjectDesc {
16 size_t num_meshes;
17 Mesh* meshes[GFX_MAX_NUM_MESHES];
18} ObjectDesc;
19
13/// Create a new object. 20/// Create a new object.
14SceneObject* gfx_make_object(); 21SceneObject* gfx_make_object(const ObjectDesc*);
15 22
16/// Destroy the object. 23/// Destroy the object.
17/// 24///
@@ -19,19 +26,10 @@ SceneObject* gfx_make_object();
19/// node is destroyed. 26/// node is destroyed.
20void gfx_destroy_object(SceneObject**); 27void gfx_destroy_object(SceneObject**);
21 28
22/// Sets the object's transformation matrix.
23void gfx_set_object_transform(SceneObject*, const mat4*);
24
25/// Add a mesh to the object.
26void gfx_add_object_mesh(SceneObject*, Mesh*);
27
28/// Remove a mesh from the object.
29void gfx_remove_object_mesh(SceneObject*, Mesh*);
30
31/// Set the object's skeleton. 29/// Set the object's skeleton.
32void gfx_set_object_skeleton(SceneObject*, const Skeleton*); 30void gfx_set_object_skeleton(SceneObject*, const Skeleton*);
33 31
34/// Computes the object's bounding box. 32/// Gets the object's bounding box.
35/// 33///
36/// The object's bounding box is the bounding box of its mesh geometries. 34/// The object's bounding box is the bounding box of its mesh geometries.
37aabb3 gfx_calc_object_aabb(const SceneObject*); 35aabb3 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(
910 for (cgltf_size m = 0; m < data->meshes_count; ++m) { 910 for (cgltf_size m = 0; m < data->meshes_count; ++m) {
911 const cgltf_mesh* mesh = &data->meshes[m]; 911 const cgltf_mesh* mesh = &data->meshes[m];
912 912
913 scene_objects[m] = gfx_make_object(); 913 ObjectDesc object_desc = {0};
914 if (!scene_objects[m]) {
915 return false;
916 }
917 914
918 for (cgltf_size p = 0; p < mesh->primitives_count; ++p) { 915 for (cgltf_size p = 0; p < mesh->primitives_count; ++p) {
919 assert(next_mesh < primitive_count); 916 assert(next_mesh < primitive_count);
@@ -1173,11 +1170,18 @@ static bool load_meshes(
1173 return false; 1170 return false;
1174 } 1171 }
1175 1172
1176 gfx_add_object_mesh(scene_objects[m], meshes[next_mesh]); 1173 assert(object_desc.num_meshes < GFX_MAX_NUM_MESHES);
1174 object_desc.meshes[object_desc.num_meshes] = meshes[next_mesh];
1175 object_desc.num_meshes++;
1177 1176
1178 ++next_mesh; 1177 ++next_mesh;
1179 } // glTF mesh primitive / gfx Mesh. 1178 } // glTF mesh primitive / gfx Mesh.
1180 } // glTF mesh / gfx SceneObject. 1179
1180 scene_objects[m] = gfx_make_object(&object_desc);
1181 if (!scene_objects[m]) {
1182 return false;
1183 }
1184 } // glTF mesh / gfx SceneObject.
1181 1185
1182 return true; 1186 return true;
1183} 1187}
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(
241 241
242 // TODO: Avoid computing matrices like Modelview or MVP if the shader does 242 // TODO: Avoid computing matrices like Modelview or MVP if the shader does
243 // not use them. 243 // not use them.
244 const mat4 model_matrix = mat4_mul(node_transform, object->transform); 244 const mat4 model_matrix = node_transform;
245 const mat4 modelview = mat4_mul(*state->view_matrix, model_matrix); 245 const mat4 modelview = mat4_mul(*state->view_matrix, model_matrix);
246 const mat4 mvp = mat4_mul(*state->projection, modelview); 246 const mat4 mvp = mat4_mul(*state->projection, modelview);
247 247
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 @@
8 8
9#include <assert.h> 9#include <assert.h>
10 10
11static void scene_object_make(SceneObject* object) { 11static aabb3 calc_object_aabb(const SceneObject* object) {
12 assert(object); 12 assert(object);
13 object->transform = mat4_id();
14}
15 13
16SceneObject* gfx_make_object() { 14 bool first = true;
17 SceneObject* object = mem_alloc_object(); 15 aabb3 box;
18 scene_object_make(object);
19 return object;
20}
21 16
22void gfx_destroy_object(SceneObject** object) { 17 mesh_link_idx ml = object->mesh_link;
23 assert(object); 18 while (ml.val) {
24 if (*object) { 19 const MeshLink* mesh_link = mem_get_mesh_link(ml);
25 if ((*object)->parent.val) { 20 const mesh_idx mi = mesh_link->mesh;
26 gfx_del_node((*object)->parent); 21 if (mi.val) {
22 const Mesh* mesh = mem_get_mesh(mi);
23 const aabb3 mesh_box = gfx_get_geometry_aabb(mesh->geometry);
24 if (first) {
25 box = mesh_box;
26 first = false;
27 } else {
28 box = aabb3_sum(box, mesh_box);
29 }
27 } 30 }
28 mem_free_object(object); 31 ml = mesh_link->next;
29 } 32 }
30}
31 33
32void gfx_set_object_transform(SceneObject* object, const mat4* transform) { 34 return box;
33 assert(object);
34 assert(transform);
35 object->transform = *transform;
36} 35}
37 36
38void gfx_add_object_mesh(SceneObject* object, Mesh* mesh) { 37static void add_object_mesh(SceneObject* object, Mesh* mesh) {
39 assert(object); 38 assert(object);
40 assert(mesh); 39 assert(mesh);
41 40
42 MeshLink* link = mem_alloc_mesh_link(); 41 MeshLink* link = mem_alloc_mesh_link();
43 assert(link);
44 link->mesh = mem_get_mesh_index(mesh); 42 link->mesh = mem_get_mesh_index(mesh);
45 link->next = object->mesh_link; 43 link->next = object->mesh_link;
46 object->mesh_link = mem_get_mesh_link_index(link); 44 object->mesh_link = mem_get_mesh_link_index(link);
47} 45}
48 46
49void gfx_remove_object_mesh(SceneObject* object, Mesh* mesh) { 47SceneObject* gfx_make_object(const ObjectDesc* desc) {
50 assert(object); 48 assert(desc);
51 assert(mesh); 49
50 SceneObject* object = mem_alloc_object();
51 for (size_t i = 0; i < desc->num_meshes; ++i) {
52 add_object_mesh(object, desc->meshes[i]);
53 }
54 object->box = calc_object_aabb(object);
55 return object;
56}
52 57
53 MeshLink* prev = 0; 58void gfx_destroy_object(SceneObject** object) {
54 const mesh_idx mesh_index = mem_get_mesh_index(mesh); 59 assert(object);
55 60
56 // Find the MeshLink in the object that contains the given mesh. 61 if (*object) {
57 for (mesh_link_idx mesh_link_index = object->mesh_link; 62 if ((*object)->parent.val) {
58 mesh_link_index.val;) { 63 gfx_del_node((*object)->parent);
59 MeshLink* mesh_link = mem_get_mesh_link(mesh_link_index);
60 if (mesh_link->mesh.val == mesh_index.val) {
61 if (prev) {
62 prev->next = mesh_link->next;
63 } else {
64 object->mesh_link = mesh_link->next;
65 }
66 mem_free_mesh_link(&mesh_link);
67 break;
68 } 64 }
69 prev = mesh_link; 65 mem_free_object(object);
70 mesh_link_index = mesh_link->next;
71 } 66 }
72} 67}
73 68
@@ -77,31 +72,7 @@ void gfx_set_object_skeleton(SceneObject* object, const Skeleton* skeleton) {
77 object->skeleton = mem_get_skeleton_index(skeleton); 72 object->skeleton = mem_get_skeleton_index(skeleton);
78} 73}
79 74
80// TODO: Could compute just once if we changed the Object API to require an 75aabb3 gfx_get_object_aabb(const SceneObject* object) {
81// object descriptor up front instead of allowing the client to add meshes
82// and skeletons dynamically.
83aabb3 gfx_calc_object_aabb(const SceneObject* object) {
84 assert(object); 76 assert(object);
85 77 return object->box;
86 bool first = true;
87 aabb3 box;
88
89 mesh_link_idx ml = object->mesh_link;
90 while (ml.val) {
91 const MeshLink* mesh_link = mem_get_mesh_link(ml);
92 const mesh_idx mi = mesh_link->mesh;
93 if (mi.val) {
94 const Mesh* mesh = mem_get_mesh(mi);
95 const aabb3 mesh_box = gfx_get_geometry_aabb(mesh->geometry);
96 if (first) {
97 box = mesh_box;
98 first = false;
99 } else {
100 box = aabb3_sum(box, mesh_box);
101 }
102 }
103 ml = mesh_link->next;
104 }
105
106 return box;
107} 78}
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 {
19/// different for each SceneObject. Each SceneObject may then have a unique list 19/// different for each SceneObject. Each SceneObject may then have a unique list
20/// of Meshes, and the Meshes are re-used. 20/// of Meshes, and the Meshes are re-used.
21typedef struct SceneObject { 21typedef struct SceneObject {
22 mat4 transform; 22 mesh_link_idx mesh_link; /// First MeshLink in the list.
23 mesh_link_idx mesh_link; // First MeshLink in the list.
24 skeleton_idx skeleton; 23 skeleton_idx skeleton;
25 node_idx parent; // Parent SceneNode. 24 node_idx parent; /// Parent SceneNode.
25 aabb3 box;
26} SceneObject; 26} 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(
56 goto cleanup; 56 goto cleanup;
57 } 57 }
58 58
59 object = gfx_make_object(); 59 object = gfx_make_object(&(ObjectDesc){.num_meshes = 1, .meshes = {mesh}});
60 if (!object) { 60 if (!object) {
61 goto cleanup; 61 goto cleanup;
62 } 62 }
63 gfx_add_object_mesh(object, mesh);
64 63
65 return object; 64 return object;
66 65