From 29af7cf14cd55ece0a8c8b1305f3b71ab57bebd6 Mon Sep 17 00:00:00 2001
From: 3gg <3gg@shellblade.net>
Date: Fri, 26 May 2023 19:12:59 -0700
Subject: Add bounding boxes and an immediate mode renderer. Pending proper
 bounding boxes for animated meshes.

---
 gltfview/src/game.c | 41 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 3 deletions(-)

(limited to 'gltfview/src')

diff --git a/gltfview/src/game.c b/gltfview/src/game.c
index f822b08..662272c 100644
--- a/gltfview/src/game.c
+++ b/gltfview/src/game.c
@@ -2,6 +2,7 @@
 
 #include <gfx/error.h>
 #include <gfx/render_backend.h>
+#include <gfx/scene/camera.h>
 #include <gfx/scene/light.h>
 #include <gfx/scene/material.h>
 #include <gfx/scene/mesh.h>
@@ -32,8 +33,10 @@ static const char* FLIGHT_HELMET =
     "/assets/glTF-Sample-Models/2.0/FlightHelmet/glTF/FlightHelmet.gltf";
 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";
 
-#define DEFAULT_SCENE_FILE DAMAGED_HELMET
+#define DEFAULT_SCENE_FILE GIRL
 
 static const char* CLOUDS1_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp";
 
@@ -189,6 +192,26 @@ static bool load_texture_debugger_scene(Game* game) {
   return true;
 }
 
+/// Render the bounding boxes of all scene objects.
+static void render_bounding_boxes(ImmRenderer* imm, const SceneNode* node) {
+  if (gfx_get_node_type(node) == 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?
+    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);
+    gfx_imm_set_model_matrix(imm, &model);
+    gfx_imm_draw_aabb(imm, box);
+  }
+
+  // Render children's boxes.
+  for (NodeIter it = gfx_get_node_child(node); it;
+       it          = gfx_get_next_child(it)) {
+    render_bounding_boxes(imm, gfx_get_iter_node(it));
+  }
+}
+
 bool game_new(Game* game, int argc, const char** argv) {
   // TODO: getopt() to implement proper argument parsing.
   const char* scene_filepath = argc > 1 ? argv[1] : DEFAULT_SCENE_FILE;
@@ -239,6 +262,8 @@ void game_end(Game* game) { gfx_destroy(&game->gfx); }
 void game_update(Game* game, double t, double dt) {
   // LOGD("Tick");
 
+  // TODO: Animation should be handled by Gfx instead. Descend through the scene
+  // looking for animas and animate them. gfx_animate(t).
   Anima* anima = gfx_get_node_anima(game->root_node);
   gfx_update_animation(anima, t);
 
@@ -263,8 +288,18 @@ void game_update(Game* game, double t, double dt) {
 }
 
 void game_render(const Game* game) {
-  gfx_render_scene(
-      game->renderer, game->render_backend, game->scene, game->camera);
+  gfx_render_scene(game->renderer, game->scene, game->camera);
+
+  ImmRenderer* imm = gfx_get_imm_renderer(game->gfx);
+  assert(imm);
+  gfx_imm_start(imm);
+  gfx_imm_set_camera(imm, gfx_get_camera_camera(game->camera));
+  gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3));
+  // DEBUG
+  // const aabb3 box = aabb3_make(vec3_make(0, 0, 0), vec3_make(1, 1, 1));
+  // gfx_imm_draw_aabb(imm, box);
+  render_bounding_boxes(imm, gfx_get_scene_root(game->scene));
+  gfx_imm_end(imm);
 }
 
 void game_set_viewport(Game* game, int width, int height) {
-- 
cgit v1.2.3