diff options
-rw-r--r-- | game/src/plugins/viewer.c | 19 | ||||
-rw-r--r-- | gfx/include/gfx/renderer.h | 4 | ||||
-rw-r--r-- | gfx/include/gfx/scene/model.h | 3 | ||||
-rw-r--r-- | gfx/include/gfx/scene/node.h | 21 | ||||
-rw-r--r-- | gfx/src/renderer/renderer.c | 33 | ||||
-rw-r--r-- | gfx/src/scene/model.c | 4 | ||||
-rw-r--r-- | gfx/src/scene/node.c | 29 |
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. |
36 | void gfx_render_scene(Renderer*, const RenderSceneParams*); | 37 | void gfx_render_scene(Renderer*, const RenderSceneParams*); |
37 | 38 | ||
39 | /// Update the scene. | ||
40 | void 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. |
11 | const SceneNode* gfx_get_model_root(const Model*); | 11 | const SceneNode* gfx_get_model_root(const Model*); |
12 | |||
13 | /// Return the model's root node. | ||
14 | SceneNode* 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; | |||
13 | typedef struct SceneCamera SceneCamera; | 13 | typedef struct SceneCamera SceneCamera; |
14 | typedef struct SceneObject SceneObject; | 14 | typedef struct SceneObject SceneObject; |
15 | 15 | ||
16 | /// Scene node iterator. | ||
17 | typedef uint32_t NodeIter; | ||
18 | |||
19 | /// Scene node type. | 16 | /// Scene node type. |
20 | typedef enum NodeType { | 17 | typedef 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. |
117 | const SceneNode* gfx_get_node_parent(const SceneNode*); | 114 | const 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. |
120 | NodeIter gfx_get_node_child(const SceneNode*); | 117 | const SceneNode* gfx_get_node_child(const SceneNode*); |
121 | |||
122 | /// Get the iterator's next sibling node. | ||
123 | NodeIter gfx_get_next_child(NodeIter); | ||
124 | 118 | ||
125 | // TODO: Think about NodeIter and NodeIterMut for const safety. | 119 | /// Get the node's first child. |
120 | SceneNode* gfx_get_node_child_mut(SceneNode*); | ||
126 | 121 | ||
127 | /// Get a scene node from the iterator. | 122 | /// Get the node's immediate sibling. |
128 | const SceneNode* gfx_get_iter_node(NodeIter); | 123 | const SceneNode* gfx_get_node_sibling(const SceneNode*); |
129 | 124 | ||
130 | /// Get a scene node from the iterator. | 125 | /// Get the node's immediate sibling. |
131 | SceneNode* gfx_get_iter_node_mut(NodeIter); | 126 | SceneNode* gfx_get_node_sibling_mut(SceneNode*); |
132 | 127 | ||
133 | /// Get the node's (local) transform. | 128 | /// Get the node's (local) transform. |
134 | mat4 gfx_get_node_transform(const SceneNode*); | 129 | mat4 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 | |||
367 | static 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 | |||
392 | void 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 | |||
43 | SceneNode* 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 | ||
237 | NodeIter gfx_get_node_child(const SceneNode* node) { | 237 | const 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 | ||
242 | NodeIter gfx_get_next_child(NodeIter it) { | 246 | SceneNode* 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 | ||
251 | const SceneNode* gfx_get_iter_node(NodeIter it) { | 250 | const 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 | ||
258 | SceneNode* gfx_get_iter_node_mut(NodeIter it) { | 259 | SceneNode* 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 | ||
262 | mat4 gfx_get_node_transform(const SceneNode* node) { | 263 | mat4 gfx_get_node_transform(const SceneNode* node) { |