diff options
author | 3gg <3gg@shellblade.net> | 2024-03-02 07:47:29 -0800 |
---|---|---|
committer | 3gg <3gg@shellblade.net> | 2024-03-02 07:47:29 -0800 |
commit | 4bc4ca2796bd434880b77d3c4bcbb56107456777 (patch) | |
tree | 6fc4280d14740108a6ace0963d9a4b0ef99f38ef /game/src/plugins | |
parent | daaa3ef68705da389d39ef625840bf5278b25f22 (diff) |
Compute joint bounding boxes.
Diffstat (limited to 'game/src/plugins')
-rw-r--r-- | game/src/plugins/viewer.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c index 4f4ef03..5e8d7d3 100644 --- a/game/src/plugins/viewer.c +++ b/game/src/plugins/viewer.c | |||
@@ -7,6 +7,8 @@ | |||
7 | #include <math/camera.h> | 7 | #include <math/camera.h> |
8 | #include <math/spatial3.h> | 8 | #include <math/spatial3.h> |
9 | 9 | ||
10 | #include <log/log.h> | ||
11 | |||
10 | #include <stdlib.h> | 12 | #include <stdlib.h> |
11 | 13 | ||
12 | // Paths to various scene files. | 14 | // Paths to various scene files. |
@@ -20,6 +22,8 @@ static const char* DAMAGED_HELMET = | |||
20 | "/assets/glTF-Sample-Models/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf"; | 22 | "/assets/glTF-Sample-Models/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf"; |
21 | static const char* GIRL = | 23 | static const char* GIRL = |
22 | "/home/jeanne/Nextcloud/assets/models/girl/girl-with-ground.gltf"; | 24 | "/home/jeanne/Nextcloud/assets/models/girl/girl-with-ground.gltf"; |
25 | static const char* BOXES = | ||
26 | "/home/jeanne/Nextcloud/assets/models/boxes/boxes.gltf"; | ||
23 | 27 | ||
24 | #define DEFAULT_SCENE_FILE GIRL | 28 | #define DEFAULT_SCENE_FILE GIRL |
25 | 29 | ||
@@ -167,43 +171,48 @@ void update(Game* game, State* state, double t, double dt) { | |||
167 | } | 171 | } |
168 | 172 | ||
169 | /// Render the bounding boxes of all scene objects. | 173 | /// Render the bounding boxes of all scene objects. |
170 | static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { | 174 | static void render_bounding_boxes_rec( |
175 | ImmRenderer* imm, const Anima* anima, const mat4* parent_model_matrix, | ||
176 | const SceneNode* node) { | ||
171 | assert(imm); | 177 | assert(imm); |
172 | assert(node); | 178 | assert(node); |
173 | 179 | ||
180 | const mat4 model_matrix = | ||
181 | mat4_mul(*parent_model_matrix, gfx_get_node_transform(node)); | ||
182 | |||
174 | const NodeType node_type = gfx_get_node_type(node); | 183 | const NodeType node_type = gfx_get_node_type(node); |
175 | 184 | ||
176 | if (node_type == ModelNode) { | 185 | if (node_type == ModelNode) { |
177 | const Model* model = gfx_get_node_model(node); | 186 | const Model* model = gfx_get_node_model(node); |
178 | const SceneNode* root = gfx_get_model_root(model); | 187 | const SceneNode* root = gfx_get_model_root(model); |
179 | render_bounding_boxes_rec(imm, root); | 188 | render_bounding_boxes_rec(imm, anima, &model_matrix, root); |
189 | } else if (node_type == AnimaNode) { | ||
190 | anima = gfx_get_node_anima(node); | ||
180 | } else if (node_type == ObjectNode) { | 191 | } else if (node_type == ObjectNode) { |
181 | // TODO: Look at the scene log. The JointNodes are detached from the | 192 | gfx_imm_set_model_matrix(imm, &model_matrix); |
182 | // ObjectNodes. This is why the boxes are not being transformed as expected | 193 | |
183 | // here. Anima needs to animate boxes? Use OOBB in addition to AABB? | 194 | const SceneObject* obj = gfx_get_node_object(node); |
184 | // | 195 | const Skeleton* skeleton = gfx_get_object_skeleton(obj); |
185 | // TODO: Idea: when a model is loaded, compute an OOBB per joint using the | 196 | |
186 | // vertices that are affected by the joint. Then transform this OOBB when | 197 | if (skeleton) { // Animated model. |
187 | // animating the skeleton. Start with AABB for simplicity. The AABB/OOBB | 198 | assert(anima); |
188 | // in the skeleton should be const. The transform AABB/OOBB is derived | 199 | const size_t num_joints = gfx_get_skeleton_num_joints(skeleton); |
189 | // on demand. Stack allocator would be best for this kind of per-frame | 200 | for (size_t i = 0; i < num_joints; ++i) { |
190 | // data. | 201 | if (gfx_joint_has_box(anima, skeleton, i)) { |
191 | // | 202 | const Box box = gfx_get_joint_box(anima, skeleton, i); |
192 | // TODO: After computing joint AABB/OOBBs, check here whether the node has | 203 | gfx_imm_draw_box3(imm, box.vertices); |
193 | // a skeleton, and if so, render the skeleton's boxes instead of the | 204 | } |
194 | // node's (the node's boxes are not animated, but computer from the rest | 205 | } |
195 | // pose). | 206 | } else { // Static model. |
196 | const mat4 model = gfx_get_node_global_transform(node); | 207 | const aabb3 box = gfx_get_object_aabb(obj); |
197 | const SceneObject* obj = gfx_get_node_object(node); | 208 | gfx_imm_draw_aabb3(imm, box); |
198 | const aabb3 box = gfx_get_object_aabb(obj); | 209 | } |
199 | gfx_imm_set_model_matrix(imm, &model); | ||
200 | gfx_imm_draw_aabb3(imm, box); | ||
201 | } | 210 | } |
202 | 211 | ||
203 | // Render children's boxes. | 212 | // Render children's boxes. |
204 | const SceneNode* child = gfx_get_node_child(node); | 213 | const SceneNode* child = gfx_get_node_child(node); |
205 | while (child) { | 214 | while (child) { |
206 | render_bounding_boxes_rec(imm, child); | 215 | render_bounding_boxes_rec(imm, anima, &model_matrix, child); |
207 | child = gfx_get_node_sibling(child); | 216 | child = gfx_get_node_sibling(child); |
208 | } | 217 | } |
209 | } | 218 | } |
@@ -218,17 +227,20 @@ static void render_bounding_boxes(const Game* game, const State* state) { | |||
218 | assert(render_backend); | 227 | assert(render_backend); |
219 | assert(imm); | 228 | assert(imm); |
220 | 229 | ||
230 | const mat4 id = mat4_id(); | ||
231 | Anima* anima = 0; | ||
232 | |||
221 | gfx_set_blending(render_backend, true); | 233 | gfx_set_blending(render_backend, true); |
222 | gfx_set_depth_mask(render_backend, false); | 234 | gfx_set_depth_mask(render_backend, false); |
223 | gfx_set_polygon_offset(render_backend, 0.5f, 0.5f); | 235 | gfx_set_polygon_offset(render_backend, -1.5f, -1.0f); |
224 | 236 | ||
225 | gfx_imm_start(imm); | 237 | gfx_imm_start(imm); |
226 | gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera)); | 238 | gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera)); |
227 | gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3)); | 239 | gfx_imm_set_colour(imm, vec4_make(0.3, 0.3, 0.9, 0.1)); |
228 | render_bounding_boxes_rec(imm, gfx_get_scene_root(state->scene)); | 240 | render_bounding_boxes_rec(imm, anima, &id, gfx_get_scene_root(state->scene)); |
229 | gfx_imm_end(imm); | 241 | gfx_imm_end(imm); |
230 | 242 | ||
231 | gfx_set_polygon_offset(render_backend, 0.0f, 0.0f); | 243 | gfx_reset_polygon_offset(render_backend); |
232 | gfx_set_depth_mask(render_backend, true); | 244 | gfx_set_depth_mask(render_backend, true); |
233 | gfx_set_blending(render_backend, false); | 245 | gfx_set_blending(render_backend, false); |
234 | } | 246 | } |