summaryrefslogtreecommitdiff
path: root/game
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-03-02 07:47:29 -0800
committer3gg <3gg@shellblade.net>2024-03-02 07:47:29 -0800
commit4bc4ca2796bd434880b77d3c4bcbb56107456777 (patch)
tree6fc4280d14740108a6ace0963d9a4b0ef99f38ef /game
parentdaaa3ef68705da389d39ef625840bf5278b25f22 (diff)
Compute joint bounding boxes.
Diffstat (limited to 'game')
-rw-r--r--game/src/plugins/viewer.c66
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";
21static const char* GIRL = 23static 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";
25static 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.
170static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { 174static 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}