summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/src/plugins/viewer.c19
-rw-r--r--gfx/include/gfx/renderer.h4
-rw-r--r--gfx/include/gfx/scene/model.h3
-rw-r--r--gfx/include/gfx/scene/node.h21
-rw-r--r--gfx/src/renderer/renderer.c33
-rw-r--r--gfx/src/scene/model.c4
-rw-r--r--gfx/src/scene/node.c29
7 files changed, 74 insertions, 39 deletions
diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c
index 945a422..88821af 100644
--- a/game/src/plugins/viewer.c
+++ b/game/src/plugins/viewer.c
@@ -155,21 +155,15 @@ void update(Game* game, State* state, double t, double dt) {
155 assert(state->scene); 155 assert(state->scene);
156 assert(state->camera); 156 assert(state->camera);
157 157
158 // TODO: Move this to some sort of update_scene(). Note that models do not
159 // need to be animated if they are not visible to the camera. The camera
160 // update also should happen first.
161 Anima* anima = gfx_get_model_anima(state->model);
162 if (anima) {
163 gfx_update_animation(anima, (R)t);
164 }
165
166 const vec3 orbit_point = vec3_make(0, 2, 0); 158 const vec3 orbit_point = vec3_make(0, 2, 0);
167 Camera* camera = gfx_get_camera_camera(state->camera); 159 Camera* camera = gfx_get_camera_camera(state->camera);
168 spatial3_orbit( 160 spatial3_orbit(
169 &camera->spatial, orbit_point, 161 &camera->spatial, orbit_point,
170 /*radius=*/5, 162 /*radius=*/5,
171 /*azimuth=*/t * 0.5, /*zenith=*/0); 163 /*azimuth=*/(R)(t * 0.5), /*zenith=*/0);
172 spatial3_lookat(&camera->spatial, orbit_point); 164 spatial3_lookat(&camera->spatial, orbit_point);
165
166 gfx_update(state->scene, state->camera, (R)t);
173} 167}
174 168
175/// Render the bounding boxes of all scene objects. 169/// Render the bounding boxes of all scene objects.
@@ -207,9 +201,10 @@ static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) {
207 } 201 }
208 202
209 // Render children's boxes. 203 // Render children's boxes.
210 for (NodeIter it = gfx_get_node_child(node); it; 204 const SceneNode* child = gfx_get_node_child(node);
211 it = gfx_get_next_child(it)) { 205 while (child) {
212 render_bounding_boxes_rec(imm, gfx_get_iter_node(it)); 206 render_bounding_boxes_rec(imm, child);
207 child = gfx_get_node_sibling(child);
213 } 208 }
214} 209}
215 210
diff --git a/gfx/include/gfx/renderer.h b/gfx/include/gfx/renderer.h
index c420889..78d8bbd 100644
--- a/gfx/include/gfx/renderer.h
+++ b/gfx/include/gfx/renderer.h
@@ -3,6 +3,7 @@
3#include <math/aabb2.h> 3#include <math/aabb2.h>
4#include <math/aabb3.h> 4#include <math/aabb3.h>
5#include <math/camera.h> 5#include <math/camera.h>
6#include <math/defs.h>
6#include <math/mat4.h> 7#include <math/mat4.h>
7#include <math/vec3.h> 8#include <math/vec3.h>
8#include <math/vec4.h> 9#include <math/vec4.h>
@@ -35,6 +36,9 @@ typedef struct RenderSceneParams {
35/// Render the scene. 36/// Render the scene.
36void gfx_render_scene(Renderer*, const RenderSceneParams*); 37void gfx_render_scene(Renderer*, const RenderSceneParams*);
37 38
39/// Update the scene.
40void gfx_update(Scene*, const SceneCamera*, R t);
41
38// ----------------------------------------------------------------------------- 42// -----------------------------------------------------------------------------
39// Immediate Mode Renderer. 43// Immediate Mode Renderer.
40// ----------------------------------------------------------------------------- 44// -----------------------------------------------------------------------------
diff --git a/gfx/include/gfx/scene/model.h b/gfx/include/gfx/scene/model.h
index f4972a9..c55fc8c 100644
--- a/gfx/include/gfx/scene/model.h
+++ b/gfx/include/gfx/scene/model.h
@@ -9,3 +9,6 @@ Anima* gfx_get_model_anima(Model*);
9 9
10/// Return the model's root node. 10/// Return the model's root node.
11const SceneNode* gfx_get_model_root(const Model*); 11const SceneNode* gfx_get_model_root(const Model*);
12
13/// Return the model's root node.
14SceneNode* gfx_get_model_root_mut(Model*);
diff --git a/gfx/include/gfx/scene/node.h b/gfx/include/gfx/scene/node.h
index d048894..77db85c 100644
--- a/gfx/include/gfx/scene/node.h
+++ b/gfx/include/gfx/scene/node.h
@@ -13,9 +13,6 @@ typedef struct Model Model;
13typedef struct SceneCamera SceneCamera; 13typedef struct SceneCamera SceneCamera;
14typedef struct SceneObject SceneObject; 14typedef struct SceneObject SceneObject;
15 15
16/// Scene node iterator.
17typedef uint32_t NodeIter;
18
19/// Scene node type. 16/// Scene node type.
20typedef enum NodeType { 17typedef enum NodeType {
21 LogicalNode, 18 LogicalNode,
@@ -116,19 +113,17 @@ SceneObject* gfx_get_node_object(const SceneNode*);
116/// Get the node's parent. 113/// Get the node's parent.
117const SceneNode* gfx_get_node_parent(const SceneNode*); 114const SceneNode* gfx_get_node_parent(const SceneNode*);
118 115
119/// Get an iterator to the node's first child. 116/// Get the node's first child.
120NodeIter gfx_get_node_child(const SceneNode*); 117const SceneNode* gfx_get_node_child(const SceneNode*);
121
122/// Get the iterator's next sibling node.
123NodeIter gfx_get_next_child(NodeIter);
124 118
125// TODO: Think about NodeIter and NodeIterMut for const safety. 119/// Get the node's first child.
120SceneNode* gfx_get_node_child_mut(SceneNode*);
126 121
127/// Get a scene node from the iterator. 122/// Get the node's immediate sibling.
128const SceneNode* gfx_get_iter_node(NodeIter); 123const SceneNode* gfx_get_node_sibling(const SceneNode*);
129 124
130/// Get a scene node from the iterator. 125/// Get the node's immediate sibling.
131SceneNode* gfx_get_iter_node_mut(NodeIter); 126SceneNode* gfx_get_node_sibling_mut(SceneNode*);
132 127
133/// Get the node's (local) transform. 128/// Get the node's (local) transform.
134mat4 gfx_get_node_transform(const SceneNode*); 129mat4 gfx_get_node_transform(const SceneNode*);
diff --git a/gfx/src/renderer/renderer.c b/gfx/src/renderer/renderer.c
index 30704e3..c72f719 100644
--- a/gfx/src/renderer/renderer.c
+++ b/gfx/src/renderer/renderer.c
@@ -363,3 +363,36 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) {
363 363
364 draw_recursively(&state, mat4_id(), scene->root); 364 draw_recursively(&state, mat4_id(), scene->root);
365} 365}
366
367static void update_rec(SceneNode* node, const SceneCamera* camera, R t) {
368 assert(node);
369 assert(camera);
370
371 const NodeType node_type = gfx_get_node_type(node);
372
373 // TODO: Models do not need to be animated if they are not visible to the
374 // camera.
375 if (node_type == AnimaNode) {
376 Anima* anima = gfx_get_node_anima(node);
377 gfx_update_animation(anima, (R)t);
378 } else if (node_type == ModelNode) {
379 Model* model = gfx_get_node_model(node);
380 SceneNode* root = gfx_get_model_root_mut(model);
381 update_rec(root, camera, t);
382 }
383
384 // Children.
385 SceneNode* child = gfx_get_node_child_mut(node);
386 while (child) {
387 update_rec(child, camera, t);
388 child = gfx_get_node_sibling_mut(child);
389 }
390}
391
392void gfx_update(Scene* scene, const SceneCamera* camera, R t) {
393 assert(scene);
394 assert(camera);
395
396 SceneNode* node = gfx_get_scene_root(scene);
397 update_rec(node, camera, t);
398}
diff --git a/gfx/src/scene/model.c b/gfx/src/scene/model.c
index 89ff0c3..507c478 100644
--- a/gfx/src/scene/model.c
+++ b/gfx/src/scene/model.c
@@ -39,3 +39,7 @@ const SceneNode* gfx_get_model_root(const Model* model) {
39 assert(model); 39 assert(model);
40 return mem_get_node(model->root); 40 return mem_get_node(model->root);
41} 41}
42
43SceneNode* gfx_get_model_root_mut(Model* model) {
44 return (SceneNode*)gfx_get_model_root(model);
45}
diff --git a/gfx/src/scene/node.c b/gfx/src/scene/node.c
index 0fbb696..05f6428 100644
--- a/gfx/src/scene/node.c
+++ b/gfx/src/scene/node.c
@@ -234,29 +234,30 @@ const SceneNode* gfx_get_node_parent(const SceneNode* node) {
234 return mem_get_node(node->parent); 234 return mem_get_node(node->parent);
235} 235}
236 236
237NodeIter gfx_get_node_child(const SceneNode* node) { 237const SceneNode* gfx_get_node_child(const SceneNode* node) {
238 assert(node); 238 assert(node);
239 return (NodeIter)node->child.val; 239 if (node->child.val) {
240 return mem_get_node(node->child);
241 } else {
242 return 0;
243 }
240} 244}
241 245
242NodeIter gfx_get_next_child(NodeIter it) { 246SceneNode* gfx_get_node_child_mut(SceneNode* node) {
243 if (!it) { 247 return (SceneNode*)gfx_get_node_child(node);
244 return it;
245 }
246 const SceneNode* cur_child = mem_get_node((node_idx){.val = it});
247 const node_idx next_child = cur_child->next;
248 return (NodeIter)next_child.val;
249} 248}
250 249
251const SceneNode* gfx_get_iter_node(NodeIter it) { 250const SceneNode* gfx_get_node_sibling(const SceneNode* node) {
252 if (!it) { 251 assert(node);
252 if (node->next.val) {
253 return mem_get_node(node->next);
254 } else {
253 return 0; 255 return 0;
254 } 256 }
255 return mem_get_node((node_idx){.val = it});
256} 257}
257 258
258SceneNode* gfx_get_iter_node_mut(NodeIter it) { 259SceneNode* gfx_get_node_sibling_mut(SceneNode* node) {
259 return (SceneNode*)gfx_get_iter_node(it); 260 return (SceneNode*)gfx_get_node_sibling(node);
260} 261}
261 262
262mat4 gfx_get_node_transform(const SceneNode* node) { 263mat4 gfx_get_node_transform(const SceneNode* node) {