From 4bc4ca2796bd434880b77d3c4bcbb56107456777 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 2 Mar 2024 07:47:29 -0800 Subject: Compute joint bounding boxes. --- game/src/plugins/viewer.c | 66 ++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 27 deletions(-) (limited to 'game/src') 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 @@ #include #include +#include + #include // Paths to various scene files. @@ -20,6 +22,8 @@ static const char* DAMAGED_HELMET = "/assets/glTF-Sample-Models/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf"; static const char* GIRL = "/home/jeanne/Nextcloud/assets/models/girl/girl-with-ground.gltf"; +static const char* BOXES = + "/home/jeanne/Nextcloud/assets/models/boxes/boxes.gltf"; #define DEFAULT_SCENE_FILE GIRL @@ -167,43 +171,48 @@ void update(Game* game, State* state, double t, double dt) { } /// Render the bounding boxes of all scene objects. -static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { +static void render_bounding_boxes_rec( + ImmRenderer* imm, const Anima* anima, const mat4* parent_model_matrix, + const SceneNode* node) { assert(imm); assert(node); + const mat4 model_matrix = + mat4_mul(*parent_model_matrix, gfx_get_node_transform(node)); + const NodeType node_type = gfx_get_node_type(node); if (node_type == ModelNode) { const Model* model = gfx_get_node_model(node); const SceneNode* root = gfx_get_model_root(model); - render_bounding_boxes_rec(imm, root); + render_bounding_boxes_rec(imm, anima, &model_matrix, root); + } else if (node_type == AnimaNode) { + anima = gfx_get_node_anima(node); } else if (node_type == ObjectNode) { - // TODO: Look at the scene log. The JointNodes are detached from the - // ObjectNodes. This is why the boxes are not being transformed as expected - // here. Anima needs to animate boxes? Use OOBB in addition to AABB? - // - // TODO: Idea: when a model is loaded, compute an OOBB per joint using the - // vertices that are affected by the joint. Then transform this OOBB when - // animating the skeleton. Start with AABB for simplicity. The AABB/OOBB - // in the skeleton should be const. The transform AABB/OOBB is derived - // on demand. Stack allocator would be best for this kind of per-frame - // data. - // - // TODO: After computing joint AABB/OOBBs, check here whether the node has - // a skeleton, and if so, render the skeleton's boxes instead of the - // node's (the node's boxes are not animated, but computer from the rest - // pose). - const mat4 model = gfx_get_node_global_transform(node); - const SceneObject* obj = gfx_get_node_object(node); - const aabb3 box = gfx_get_object_aabb(obj); - gfx_imm_set_model_matrix(imm, &model); - gfx_imm_draw_aabb3(imm, box); + gfx_imm_set_model_matrix(imm, &model_matrix); + + const SceneObject* obj = gfx_get_node_object(node); + const Skeleton* skeleton = gfx_get_object_skeleton(obj); + + if (skeleton) { // Animated model. + assert(anima); + const size_t num_joints = gfx_get_skeleton_num_joints(skeleton); + for (size_t i = 0; i < num_joints; ++i) { + if (gfx_joint_has_box(anima, skeleton, i)) { + const Box box = gfx_get_joint_box(anima, skeleton, i); + gfx_imm_draw_box3(imm, box.vertices); + } + } + } else { // Static model. + const aabb3 box = gfx_get_object_aabb(obj); + gfx_imm_draw_aabb3(imm, box); + } } // Render children's boxes. const SceneNode* child = gfx_get_node_child(node); while (child) { - render_bounding_boxes_rec(imm, child); + render_bounding_boxes_rec(imm, anima, &model_matrix, child); child = gfx_get_node_sibling(child); } } @@ -218,17 +227,20 @@ static void render_bounding_boxes(const Game* game, const State* state) { assert(render_backend); assert(imm); + const mat4 id = mat4_id(); + Anima* anima = 0; + gfx_set_blending(render_backend, true); gfx_set_depth_mask(render_backend, false); - gfx_set_polygon_offset(render_backend, 0.5f, 0.5f); + gfx_set_polygon_offset(render_backend, -1.5f, -1.0f); gfx_imm_start(imm); gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera)); - gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3)); - render_bounding_boxes_rec(imm, gfx_get_scene_root(state->scene)); + gfx_imm_set_colour(imm, vec4_make(0.3, 0.3, 0.9, 0.1)); + render_bounding_boxes_rec(imm, anima, &id, gfx_get_scene_root(state->scene)); gfx_imm_end(imm); - gfx_set_polygon_offset(render_backend, 0.0f, 0.0f); + gfx_reset_polygon_offset(render_backend); gfx_set_depth_mask(render_backend, true); gfx_set_blending(render_backend, false); } -- cgit v1.2.3