aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/asset/asset_cache.c1
-rw-r--r--src/asset/model.c34
-rw-r--r--src/memory.c13
-rw-r--r--src/memory.h10
-rw-r--r--src/render/llr.c3
-rw-r--r--src/render/llr_impl.h1
-rw-r--r--src/render/renderer.c13
-rw-r--r--src/scene/animation.c10
-rw-r--r--src/scene/animation_impl.h30
-rw-r--r--src/scene/camera.c28
-rw-r--r--src/scene/camera_impl.h12
-rw-r--r--src/scene/model_impl.h1
-rw-r--r--src/scene/node.c32
-rw-r--r--src/scene/node_impl.h4
-rw-r--r--src/scene/object.c4
-rw-r--r--src/scene/object_impl.h4
-rw-r--r--src/scene/scene_graph.h2
17 files changed, 64 insertions, 138 deletions
diff --git a/src/asset/asset_cache.c b/src/asset/asset_cache.c
index a364330..191a5fd 100644
--- a/src/asset/asset_cache.c
+++ b/src/asset/asset_cache.c
@@ -167,7 +167,6 @@ static Model* clone_model(const Model* model) {
167 167
168 SceneNode* root_copy = gfx_clone_scene_shallow(root); 168 SceneNode* root_copy = gfx_clone_scene_shallow(root);
169 root_copy->anima = mem_get_anima_index(anima_copy); 169 root_copy->anima = mem_get_anima_index(anima_copy);
170 anima_copy->parent = mem_get_node_index(root_copy);
171 170
172 Model* copy = mem_alloc_model(); 171 Model* copy = mem_alloc_model();
173 copy->root = mem_get_node_index(root_copy); 172 copy->root = mem_get_node_index(root_copy);
diff --git a/src/asset/model.c b/src/asset/model.c
index ccda27d..df116fb 100644
--- a/src/asset/model.c
+++ b/src/asset/model.c
@@ -1555,7 +1555,7 @@ static void remove_joint_nodes(
1555/// and instead just loads all nodes into a single gfx Scene. 1555/// and instead just loads all nodes into a single gfx Scene.
1556static void load_nodes( 1556static void load_nodes(
1557 const cgltf_data* data, SceneNode* root_node, SceneObject** objects, 1557 const cgltf_data* data, SceneNode* root_node, SceneObject** objects,
1558 SceneCamera** cameras, const Anima* anima, SceneNode** nodes) { 1558 const Anima* anima, SceneNode** nodes) {
1559 // Note that with glTF 2.0, nodes do not form a DAG / scene graph but a 1559 // Note that with glTF 2.0, nodes do not form a DAG / scene graph but a
1560 // disjoint union of strict trees: 1560 // disjoint union of strict trees:
1561 // 1561 //
@@ -1570,7 +1570,6 @@ static void load_nodes(
1570 assert(data); 1570 assert(data);
1571 assert(root_node); 1571 assert(root_node);
1572 assert(objects); 1572 assert(objects);
1573 assert(cameras);
1574 assert(nodes); 1573 assert(nodes);
1575 1574
1576 cgltf_size next_camera = 0; 1575 cgltf_size next_camera = 0;
@@ -1579,7 +1578,7 @@ static void load_nodes(
1579 for (cgltf_size n = 0; n < data->nodes_count; ++n) { 1578 for (cgltf_size n = 0; n < data->nodes_count; ++n) {
1580 const cgltf_node* node = &data->nodes[n]; 1579 const cgltf_node* node = &data->nodes[n];
1581 1580
1582 // Add SceneObject, SceneCamera or Lights. 1581 // Add SceneObject, Camera or Lights.
1583 // TODO: Handle lights once they are implemented in the gfx library. 1582 // TODO: Handle lights once they are implemented in the gfx library.
1584 assert(!nodes[n]); 1583 assert(!nodes[n]);
1585 if (node->mesh) { 1584 if (node->mesh) {
@@ -1599,29 +1598,27 @@ static void load_nodes(
1599 } else if (node->camera) { 1598 } else if (node->camera) {
1600 assert(next_camera < data->cameras_count); 1599 assert(next_camera < data->cameras_count);
1601 1600
1602 Camera camera;
1603 const cgltf_camera* cam = node->camera; 1601 const cgltf_camera* cam = node->camera;
1604 1602
1605 // TODO: We could define a function load_cameras() the same way we load 1603 // TODO: We could define a function load_cameras() the same way we load
1606 // every mesh and then remove this ad-hoc loading of cameras here, as well 1604 // every mesh and then remove this ad-hoc loading of cameras here, as well
1607 // as remove 'next_camera'. 1605 // as remove 'next_camera'.
1606 Camera* camera = gfx_make_camera();
1608 switch (cam->type) { 1607 switch (cam->type) {
1609 case cgltf_camera_type_orthographic: 1608 case cgltf_camera_type_orthographic:
1610 camera = camera_orthographic( 1609 *camera = camera_orthographic(
1611 0, cam->data.orthographic.xmag, 0, cam->data.orthographic.ymag, 1610 0, cam->data.orthographic.xmag, 0, cam->data.orthographic.ymag,
1612 cam->data.orthographic.znear, cam->data.orthographic.zfar); 1611 cam->data.orthographic.znear, cam->data.orthographic.zfar);
1613 break; 1612 break;
1614 case cgltf_camera_type_perspective: 1613 case cgltf_camera_type_perspective:
1615 camera = camera_perspective( 1614 *camera = camera_perspective(
1616 cam->data.perspective.yfov, cam->data.perspective.aspect_ratio, 1615 cam->data.perspective.yfov, cam->data.perspective.aspect_ratio,
1617 cam->data.perspective.znear, cam->data.perspective.zfar); 1616 cam->data.perspective.znear, cam->data.perspective.zfar);
1618 break; 1617 break;
1619 case cgltf_camera_type_invalid: 1618 case cgltf_camera_type_invalid:
1620 break; 1619 break;
1621 } 1620 }
1622 1621 nodes[n] = gfx_make_camera_node(camera);
1623 gfx_set_camera_camera(cameras[next_camera], &camera);
1624 nodes[n] = gfx_make_camera_node(cameras[next_camera]);
1625 ++next_camera; 1622 ++next_camera;
1626 } else { 1623 } else {
1627 // TODO: implementation for missing node types. 1624 // TODO: implementation for missing node types.
@@ -1727,7 +1724,6 @@ static Model* load_scene(
1727 Mesh** meshes = 0; 1724 Mesh** meshes = 0;
1728 AnimaDesc* anima_desc = 0; 1725 AnimaDesc* anima_desc = 0;
1729 SceneObject** scene_objects = 0; 1726 SceneObject** scene_objects = 0;
1730 SceneCamera** scene_cameras = 0;
1731 SceneNode** scene_nodes = 0; 1727 SceneNode** scene_nodes = 0;
1732 Anima* anima = 0; 1728 Anima* anima = 0;
1733 SceneNode* root_node = 0; 1729 SceneNode* root_node = 0;
@@ -1740,8 +1736,7 @@ static Model* load_scene(
1740 geometries = calloc(primitive_count, sizeof(Geometry*)); 1736 geometries = calloc(primitive_count, sizeof(Geometry*));
1741 meshes = calloc(primitive_count, sizeof(Mesh*)); 1737 meshes = calloc(primitive_count, sizeof(Mesh*));
1742 scene_objects = calloc(data->meshes_count, sizeof(SceneObject*)); 1738 scene_objects = calloc(data->meshes_count, sizeof(SceneObject*));
1743 scene_cameras = calloc(data->cameras_count, sizeof(SceneCamera**)); 1739 scene_nodes = calloc(data->nodes_count, sizeof(SceneNode*));
1744 scene_nodes = calloc(data->nodes_count, sizeof(SceneNode**));
1745 // A glTF scene does not necessarily have textures. Materials can be given 1740 // A glTF scene does not necessarily have textures. Materials can be given
1746 // as constants, for example. 1741 // as constants, for example.
1747 if (data->textures_count > 0) { 1742 if (data->textures_count > 0) {
@@ -1750,8 +1745,7 @@ static Model* load_scene(
1750 1745
1751 if (!buffers || !tangent_buffers || 1746 if (!buffers || !tangent_buffers ||
1752 ((data->textures_count > 0) && !load_texture_cmds) || !textures || 1747 ((data->textures_count > 0) && !load_texture_cmds) || !textures ||
1753 !materials || !geometries || !meshes || !scene_objects || 1748 !materials || !geometries || !meshes || !scene_objects || !scene_nodes) {
1754 !scene_cameras || !scene_nodes) {
1755 goto cleanup; 1749 goto cleanup;
1756 } 1750 }
1757 1751
@@ -1809,7 +1803,7 @@ static Model* load_scene(
1809 assert(root_node); 1803 assert(root_node);
1810 1804
1811 // The root node becomes the root of all scene nodes. 1805 // The root node becomes the root of all scene nodes.
1812 load_nodes(data, root_node, scene_objects, scene_cameras, anima, scene_nodes); 1806 load_nodes(data, root_node, scene_objects, anima, scene_nodes);
1813 1807
1814 model = gfx_make_model(root_node); 1808 model = gfx_make_model(root_node);
1815 1809
@@ -1887,16 +1881,6 @@ cleanup:
1887 } 1881 }
1888 free(scene_objects); 1882 free(scene_objects);
1889 } 1883 }
1890 if (scene_cameras) {
1891 if (!success) {
1892 for (cgltf_size i = 0; i < data->cameras_count; ++i) {
1893 if (scene_cameras[i]) {
1894 gfx_destroy_camera(&scene_cameras[i]);
1895 }
1896 }
1897 }
1898 free(scene_cameras);
1899 }
1900 if (scene_nodes) { 1884 if (scene_nodes) {
1901 if (!success) { 1885 if (!success) {
1902 for (cgltf_size i = 0; i < data->nodes_count; ++i) { 1886 for (cgltf_size i = 0; i < data->nodes_count; ++i) {
diff --git a/src/memory.c b/src/memory.c
index a68bc2b..3481791 100644
--- a/src/memory.c
+++ b/src/memory.c
@@ -1,21 +1,22 @@
1#include "memory.h" 1#include "memory.h"
2 2
3#include <gfx/scene/camera.h>
3#include <gfx/sizes.h> 4#include <gfx/sizes.h>
4 5
5#include "render/llr_impl.h" 6#include "render/llr_impl.h"
6#include "scene/animation_impl.h" 7#include "scene/animation_impl.h"
7#include "scene/camera_impl.h"
8#include "scene/model_impl.h" 8#include "scene/model_impl.h"
9#include "scene/node_impl.h" 9#include "scene/node_impl.h"
10#include "scene/object_impl.h" 10#include "scene/object_impl.h"
11#include "scene/scene_impl.h" 11#include "scene/scene_impl.h"
12 12
13#include <log/log.h> 13#include <log/log.h>
14#include <math/camera.h>
14#include <mempool.h> 15#include <mempool.h>
15 16
16DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS) 17DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS)
17DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS) 18DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS)
18DEF_MEMPOOL(camera_pool, SceneCamera, GFX_MAX_NUM_CAMERAS) 19DEF_MEMPOOL(camera_pool, Camera, GFX_MAX_NUM_CAMERAS)
19DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS) 20DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS)
20DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS) 21DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS)
21DEF_MEMPOOL(mesh_pool, Mesh, GFX_MAX_NUM_MESHES) 22DEF_MEMPOOL(mesh_pool, Mesh, GFX_MAX_NUM_MESHES)
@@ -56,7 +57,7 @@ static SceneMemory mem;
56#define PLURAL(name) name##s 57#define PLURAL(name) name##s
57#define MEM_FIELD(name) mem.PLURAL(name) 58#define MEM_FIELD(name) mem.PLURAL(name)
58 59
59void scene_mem_init() { 60void scene_mem_init(void) {
60 mempool_make(&mem.animas); 61 mempool_make(&mem.animas);
61 mempool_make(&mem.animations); 62 mempool_make(&mem.animations);
62 mempool_make(&mem.cameras); 63 mempool_make(&mem.cameras);
@@ -86,7 +87,7 @@ void scene_mem_init() {
86 ALLOC_DUMMY(&mem.skeletons); 87 ALLOC_DUMMY(&mem.skeletons);
87} 88}
88 89
89void scene_mem_destroy() { 90void scene_mem_destroy(void) {
90 // NOTE: the dummy objects are not constructed, so the destruction code below 91 // NOTE: the dummy objects are not constructed, so the destruction code below
91 // always skips index 0. (I don't really like the conditional inside the loop, 92 // always skips index 0. (I don't really like the conditional inside the loop,
92 // but this gets the job done without having to specialize the loop macro.) 93 // but this gets the job done without having to specialize the loop macro.)
@@ -148,7 +149,7 @@ void scene_mem_destroy() {
148 149
149#define DEF_MEMORY(NAME, TYPE) \ 150#define DEF_MEMORY(NAME, TYPE) \
150 /* xyz* mem_alloc_xyz(); */ \ 151 /* xyz* mem_alloc_xyz(); */ \
151 TYPE* mem_alloc_##NAME() { return mempool_alloc(&MEM_FIELD(NAME)); } \ 152 TYPE* mem_alloc_##NAME(void) { return mempool_alloc(&MEM_FIELD(NAME)); } \
152 /* void mem_free_xyz(xyz**); */ \ 153 /* void mem_free_xyz(xyz**); */ \
153 void mem_free_##NAME(TYPE** obj) { mempool_free(&MEM_FIELD(NAME), obj); } \ 154 void mem_free_##NAME(TYPE** obj) { mempool_free(&MEM_FIELD(NAME), obj); } \
154 /* xyz* mem_get_xyz(xyz_idx); */ \ 155 /* xyz* mem_get_xyz(xyz_idx); */ \
@@ -164,7 +165,7 @@ void scene_mem_destroy() {
164 165
165DEF_MEMORY(anima, Anima) 166DEF_MEMORY(anima, Anima)
166DEF_MEMORY(animation, Animation) 167DEF_MEMORY(animation, Animation)
167DEF_MEMORY(camera, SceneCamera) 168DEF_MEMORY(camera, Camera)
168DEF_MEMORY(light, Light) 169DEF_MEMORY(light, Light)
169DEF_MEMORY(material, Material) 170DEF_MEMORY(material, Material)
170DEF_MEMORY(mesh, Mesh) 171DEF_MEMORY(mesh, Mesh)
diff --git a/src/memory.h b/src/memory.h
index 366c6e4..624216d 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -3,21 +3,23 @@
3 3
4#include "scene/types.h" 4#include "scene/types.h"
5 5
6typedef struct Camera Camera;
7
6/// Initialize scene memory. 8/// Initialize scene memory.
7/// 9///
8/// The scene memory guarantees that every object maps to an index different 10/// The scene memory guarantees that every object maps to an index different
9/// than 0. This way, 0 can be used as a special index to denote "no value". 11/// than 0. This way, 0 can be used as a special index to denote "no value".
10void scene_mem_init(); 12void scene_mem_init(void);
11 13
12/// Destroy the scene memory and all allocated objects. 14/// Destroy the scene memory and all allocated objects.
13void scene_mem_destroy(); 15void scene_mem_destroy(void);
14 16
15#define NAMED_INDEX(name) name##_idx 17#define NAMED_INDEX(name) name##_idx
16 18
17#define DECL_MEMORY(name, type) \ 19#define DECL_MEMORY(name, type) \
18 typedef struct type type; \ 20 typedef struct type type; \
19 /* xyz* mem_alloc_xyz() */ \ 21 /* xyz* mem_alloc_xyz() */ \
20 type* mem_alloc_##name(); \ 22 type* mem_alloc_##name(void); \
21 /* mem_free_xyz(xyz**) */ \ 23 /* mem_free_xyz(xyz**) */ \
22 void mem_free_##name(type**); \ 24 void mem_free_##name(type**); \
23 /* xyz* mem_get_xyz(xyz_idx); */ \ 25 /* xyz* mem_get_xyz(xyz_idx); */ \
@@ -27,7 +29,7 @@ void scene_mem_destroy();
27 29
28DECL_MEMORY(anima, Anima) 30DECL_MEMORY(anima, Anima)
29DECL_MEMORY(animation, Animation) 31DECL_MEMORY(animation, Animation)
30DECL_MEMORY(camera, SceneCamera) 32DECL_MEMORY(camera, Camera)
31DECL_MEMORY(light, Light) 33DECL_MEMORY(light, Light)
32DECL_MEMORY(material, Material) 34DECL_MEMORY(material, Material)
33DECL_MEMORY(mesh, Mesh) 35DECL_MEMORY(mesh, Mesh)
diff --git a/src/render/llr.c b/src/render/llr.c
index a1b37be..189041a 100644
--- a/src/render/llr.c
+++ b/src/render/llr.c
@@ -46,9 +46,6 @@ Light* gfx_make_light(const LightDesc* desc) {
46void gfx_destroy_light(Light** light) { 46void gfx_destroy_light(Light** light) {
47 assert(light); 47 assert(light);
48 if (*light) { 48 if (*light) {
49 if ((*light)->parent.val) {
50 gfx_del_node((*light)->parent);
51 }
52 mem_free_light(light); 49 mem_free_light(light);
53 } 50 }
54} 51}
diff --git a/src/render/llr_impl.h b/src/render/llr_impl.h
index 319441c..1c08b03 100644
--- a/src/render/llr_impl.h
+++ b/src/render/llr_impl.h
@@ -34,7 +34,6 @@ typedef struct Light {
34 union { 34 union {
35 EnvironmentLight environment; 35 EnvironmentLight environment;
36 }; 36 };
37 node_idx parent; // Parent SceneNode.
38} Light; 37} Light;
39 38
40typedef struct Material { 39typedef struct Material {
diff --git a/src/render/renderer.c b/src/render/renderer.c
index eca7551..385a8c1 100644
--- a/src/render/renderer.c
+++ b/src/render/renderer.c
@@ -3,7 +3,6 @@
3#include "llr_impl.h" 3#include "llr_impl.h"
4#include "memory.h" 4#include "memory.h"
5#include "scene/animation_impl.h" 5#include "scene/animation_impl.h"
6#include "scene/camera_impl.h"
7#include "scene/model_impl.h" 6#include "scene/model_impl.h"
8#include "scene/node_impl.h" 7#include "scene/node_impl.h"
9#include "scene/object_impl.h" 8#include "scene/object_impl.h"
@@ -192,9 +191,9 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) {
192 191
193 ShaderProgram* const shader = load_shader(renderer, params->mode); 192 ShaderProgram* const shader = load_shader(renderer, params->mode);
194 193
195 const Scene* scene = params->scene; 194 const Scene* scene = params->scene;
196 const SceneCamera* camera = params->camera; 195 const Camera* camera = params->camera;
197 GfxCore* const gfxcore = renderer->gfxcore; 196 GfxCore* const gfxcore = renderer->gfxcore;
198 197
199 int x, y, width, height; 198 int x, y, width, height;
200 gfx_get_viewport(gfxcore, &x, &y, &width, &height); 199 gfx_get_viewport(gfxcore, &x, &y, &width, &height);
@@ -207,12 +206,12 @@ void gfx_render_scene(Renderer* renderer, const RenderSceneParams* params) {
207 .shader = shader, 206 .shader = shader,
208 .scene = scene}; 207 .scene = scene};
209 208
210 gfx_llr_set_camera(renderer->llr, &camera->camera); 209 gfx_llr_set_camera(renderer->llr, camera);
211 gfx_llr_set_aspect(renderer->llr, aspect); 210 gfx_llr_set_aspect(renderer->llr, aspect);
212 draw_recursively(&state, mat4_id(), scene->root); 211 draw_recursively(&state, mat4_id(), scene->root);
213} 212}
214 213
215static void update_rec(SceneNode* node, const SceneCamera* camera, R t) { 214static void update_rec(SceneNode* node, const Camera* camera, R t) {
216 assert(node); 215 assert(node);
217 assert(camera); 216 assert(camera);
218 217
@@ -237,7 +236,7 @@ static void update_rec(SceneNode* node, const SceneCamera* camera, R t) {
237 } 236 }
238} 237}
239 238
240void gfx_update(Scene* scene, const SceneCamera* camera, R t) { 239void gfx_update(Scene* scene, const Camera* camera, R t) {
241 assert(scene); 240 assert(scene);
242 assert(camera); 241 assert(camera);
243 242
diff --git a/src/scene/animation.c b/src/scene/animation.c
index 601c400..a498961 100644
--- a/src/scene/animation.c
+++ b/src/scene/animation.c
@@ -204,10 +204,6 @@ void gfx_destroy_anima(Anima** anima) {
204 mem_free_animation(&animation); 204 mem_free_animation(&animation);
205 } 205 }
206 206
207 if ((*anima)->parent.val) {
208 gfx_del_node((*anima)->parent);
209 }
210
211 mem_free_anima(anima); 207 mem_free_anima(anima);
212 } 208 }
213} 209}
@@ -450,10 +446,8 @@ void gfx_update_animation(Anima* anima, R t) {
450 // which we have constructed to be the common root of all skeletons. 446 // which we have constructed to be the common root of all skeletons.
451 // 447 //
452 // This procedure touches every joint exactly once. 448 // This procedure touches every joint exactly once.
453 SceneNode* root_node = mem_get_node(anima->parent); 449 const mat4 root_global_transform = mat4_id();
454 // LOGD("Root: %u, child: %u", anima->parent.val, root->child.val); 450 const mat4 root_inv_global_transform = mat4_id();
455 const mat4 root_global_transform = gfx_get_node_global_transform(root_node);
456 const mat4 root_inv_global_transform = mat4_inverse(root_global_transform);
457 451
458 Joint* root_joint = get_anima_root_joint(anima); 452 Joint* root_joint = get_anima_root_joint(anima);
459 compute_joint_matrices_rec( 453 compute_joint_matrices_rec(
diff --git a/src/scene/animation_impl.h b/src/scene/animation_impl.h
index 4408158..ef1492c 100644
--- a/src/scene/animation_impl.h
+++ b/src/scene/animation_impl.h
@@ -12,7 +12,6 @@
12#include <math/vec3.h> 12#include <math/vec3.h>
13 13
14#include <stddef.h> 14#include <stddef.h>
15#include <stdint.h>
16 15
17typedef struct Buffer Buffer; 16typedef struct Buffer Buffer;
18 17
@@ -24,24 +23,24 @@ typedef struct Buffer Buffer;
24/// Joints are mutable and store the transform and joint matrices that result 23/// Joints are mutable and store the transform and joint matrices that result
25/// from animation, aside from the inverse bind matrix. 24/// from animation, aside from the inverse bind matrix.
26typedef struct Joint { 25typedef struct Joint {
27 joint_idx child; /// First child Joint; index into Anima's joints. 26 joint_idx child; // First child Joint; index into Anima's joints.
28 joint_idx next; /// Next sibling Joint; index into Anima's joints. 27 joint_idx next; // Next sibling Joint; index into Anima's joints.
29 mat4 transform; /// Local transform relative to parent. 28 mat4 transform; // Local transform relative to parent.
30 mat4 inv_bind_matrix; /// Transforms the mesh into the joint's local space. 29 mat4 inv_bind_matrix; // Transforms the mesh into the joint's local space.
31 mat4 joint_matrix; /// inv(global) * global joint transform * inv(bind). 30 mat4 joint_matrix; // inv(global) * global joint transform * inv(bind).
32 aabb3 box; /// Bounding box of vertices affected by joint. 31 aabb3 box; // Bounding box of vertices affected by joint.
33} Joint; 32} Joint;
34 33
35/// Animation skeleton. 34/// Animation skeleton.
36typedef struct Skeleton { 35typedef struct Skeleton {
37 skeleton_idx next; 36 skeleton_idx next;
38 size_t num_joints; 37 size_t num_joints;
39 joint_idx joints[GFX_MAX_NUM_JOINTS]; /// Indices into Anima's joints array. 38 joint_idx joints[GFX_MAX_NUM_JOINTS]; // Indices into Anima's joints array.
40} Skeleton; 39} Skeleton;
41 40
42/// A keyframe of animation. 41/// A keyframe of animation.
43typedef struct Keyframe { 42typedef struct Keyframe {
44 R time; /// Start time in [0, end animation time] 43 R time; // Start time in [0, end animation time]
45 union { 44 union {
46 vec3 translation; 45 vec3 translation;
47 quat rotation; 46 quat rotation;
@@ -50,7 +49,7 @@ typedef struct Keyframe {
50 49
51/// Animation channel. 50/// Animation channel.
52typedef struct Channel { 51typedef struct Channel {
53 joint_idx target; /// Index into Anima's joints array. 52 joint_idx target; // Index into Anima's joints array.
54 ChannelType type; 53 ChannelType type;
55 AnimationInterpolation interpolation; 54 AnimationInterpolation interpolation;
56 size_t num_keyframes; 55 size_t num_keyframes;
@@ -89,10 +88,9 @@ typedef struct AnimationState {
89/// have no parent (a skeleton need not have its own root and can be a set of 88/// have no parent (a skeleton need not have its own root and can be a set of
90/// disjoint node hierarchies). 89/// disjoint node hierarchies).
91typedef struct Anima { 90typedef struct Anima {
92 node_idx parent; /// Parent SceneNode. 91 skeleton_idx skeleton; // Index of first skeleton.
93 skeleton_idx skeleton; /// Index of first skeleton. 92 animation_idx animation; // Index of first animation.
94 animation_idx animation; /// Index of first animation. 93 AnimationState state; // Current animation state.
95 AnimationState state; /// Current animation state. 94 size_t num_joints; // Number of actual joints in the array.
96 size_t num_joints; /// Number of actual joints in the array. 95 Joint joints[GFX_MAX_NUM_JOINTS]; // Shared by all skeletons.
97 Joint joints[GFX_MAX_NUM_JOINTS]; /// Shared by all skeletons.
98} Anima; 96} Anima;
diff --git a/src/scene/camera.c b/src/scene/camera.c
index bb073ba..475101d 100644
--- a/src/scene/camera.c
+++ b/src/scene/camera.c
@@ -1,37 +1,21 @@
1#include "camera_impl.h" 1#include <gfx/scene/camera.h>
2 2
3#include "memory.h" 3#include "memory.h"
4#include "node_impl.h"
5 4
6#include <assert.h> 5#include <assert.h>
6#include <math/camera.h>
7 7
8SceneCamera* gfx_make_camera() { 8Camera* gfx_make_camera() {
9 SceneCamera* camera = mem_alloc_camera(); 9 Camera* camera = mem_alloc_camera();
10 10 *camera = camera_perspective(
11 camera->camera = camera_perspective(
12 /*fovy=*/90.0 * TO_RAD, /*aspect=*/16.0 / 9.0, 11 /*fovy=*/90.0 * TO_RAD, /*aspect=*/16.0 / 9.0,
13 /*near=*/0.1, /*far=*/1000); 12 /*near=*/0.1, /*far=*/1000);
14
15 return camera; 13 return camera;
16} 14}
17 15
18void gfx_destroy_camera(SceneCamera** camera) { 16void gfx_destroy_camera(Camera** camera) {
19 assert(camera); 17 assert(camera);
20 if (*camera) { 18 if (*camera) {
21 if ((*camera)->parent.val) {
22 gfx_del_node((*camera)->parent);
23 }
24 mem_free_camera(camera); 19 mem_free_camera(camera);
25 } 20 }
26} 21}
27
28void gfx_set_camera_camera(SceneCamera* scene_camera, Camera* camera) {
29 assert(scene_camera);
30 assert(camera);
31 scene_camera->camera = *camera;
32}
33
34Camera* gfx_get_camera_camera(SceneCamera* camera) {
35 assert(camera);
36 return &camera->camera;
37}
diff --git a/src/scene/camera_impl.h b/src/scene/camera_impl.h
deleted file mode 100644
index 20c3890..0000000
--- a/src/scene/camera_impl.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#pragma once
2
3#include <gfx/scene/camera.h>
4
5#include "types.h"
6
7#include <math/camera.h>
8
9typedef struct SceneCamera {
10 Camera camera;
11 node_idx parent; // Parent SceneNode.
12} SceneCamera;
diff --git a/src/scene/model_impl.h b/src/scene/model_impl.h
index 39ac27f..079aede 100644
--- a/src/scene/model_impl.h
+++ b/src/scene/model_impl.h
@@ -7,7 +7,6 @@
7/// Model. 7/// Model.
8typedef struct Model { 8typedef struct Model {
9 node_idx root; 9 node_idx root;
10 node_idx parent; // Parent SceneNode.
11} Model; 10} Model;
12 11
13/// Create a new model. 12/// Create a new model.
diff --git a/src/scene/node.c b/src/scene/node.c
index 7cc315c..7032324 100644
--- a/src/scene/node.c
+++ b/src/scene/node.c
@@ -1,15 +1,15 @@
1#include "node_impl.h" 1#include "node_impl.h"
2 2
3#include "animation_impl.h" 3#include "animation_impl.h"
4#include "camera_impl.h"
5#include "memory.h" 4#include "memory.h"
6#include "model_impl.h"
7#include "object_impl.h" 5#include "object_impl.h"
8#include "render/llr_impl.h" 6#include "render/llr_impl.h"
9#include "scene_graph.h" 7#include "scene_graph.h"
10 8
11#include "gfx_assert.h" 9#include "gfx_assert.h"
12 10
11#include <gfx/scene/camera.h>
12
13#include <cstring.h> 13#include <cstring.h>
14#include <log/log.h> 14#include <log/log.h>
15 15
@@ -19,7 +19,7 @@ static void scene_node_make(SceneNode* node) {
19 node->transform = mat4_id(); 19 node->transform = mat4_id();
20} 20}
21 21
22SceneNode* gfx_make_node() { 22SceneNode* gfx_make_node(void) {
23 SceneNode* node = mem_alloc_node(); 23 SceneNode* node = mem_alloc_node();
24 scene_node_make(node); 24 scene_node_make(node);
25 return node; 25 return node;
@@ -30,16 +30,14 @@ SceneNode* gfx_make_anima_node(Anima* anima) {
30 SceneNode* node = gfx_make_node(); 30 SceneNode* node = gfx_make_node();
31 node->type = AnimaNode; 31 node->type = AnimaNode;
32 node->anima = mem_get_anima_index(anima); 32 node->anima = mem_get_anima_index(anima);
33 anima->parent = mem_get_node_index(node);
34 return node; 33 return node;
35} 34}
36 35
37SceneNode* gfx_make_camera_node(SceneCamera* camera) { 36SceneNode* gfx_make_camera_node(Camera* camera) {
38 assert(camera); 37 assert(camera);
39 SceneNode* node = gfx_make_node(); 38 SceneNode* node = gfx_make_node();
40 node->type = CameraNode; 39 node->type = CameraNode;
41 node->camera = mem_get_camera_index(camera); 40 node->camera = mem_get_camera_index(camera);
42 camera->parent = mem_get_node_index(node);
43 return node; 41 return node;
44} 42}
45 43
@@ -48,7 +46,6 @@ SceneNode* gfx_make_light_node(Light* light) {
48 SceneNode* node = gfx_make_node(); 46 SceneNode* node = gfx_make_node();
49 node->type = LightNode; 47 node->type = LightNode;
50 node->light = mem_get_light_index(light); 48 node->light = mem_get_light_index(light);
51 light->parent = mem_get_node_index(node);
52 return node; 49 return node;
53} 50}
54 51
@@ -57,7 +54,6 @@ SceneNode* gfx_make_model_node(Model* model) {
57 SceneNode* node = gfx_make_node(); 54 SceneNode* node = gfx_make_node();
58 node->type = ModelNode; 55 node->type = ModelNode;
59 node->model = mem_get_model_index(model); 56 node->model = mem_get_model_index(model);
60 model->parent = mem_get_node_index(node);
61 return node; 57 return node;
62} 58}
63 59
@@ -66,7 +62,6 @@ SceneNode* gfx_make_object_node(SceneObject* object) {
66 SceneNode* node = gfx_make_node(); 62 SceneNode* node = gfx_make_node();
67 node->type = ObjectNode; 63 node->type = ObjectNode;
68 node->object = mem_get_object_index(object); 64 node->object = mem_get_object_index(object);
69 object->parent = mem_get_node_index(node);
70 return node; 65 return node;
71} 66}
72 67
@@ -74,24 +69,19 @@ SceneNode* gfx_make_object_node(SceneObject* object) {
74static void free_node_resource(SceneNode* node) { 69static void free_node_resource(SceneNode* node) {
75 assert(node); 70 assert(node);
76 71
77 // Set the resource's parent node back to 0 to avoid a recursive call into
78 // gfx_del_node().
79 switch (node->type) { 72 switch (node->type) {
80 case AnimaNode: { 73 case AnimaNode: {
81 Anima* anima = mem_get_anima(node->anima); 74 Anima* anima = mem_get_anima(node->anima);
82 anima->parent.val = 0;
83 gfx_destroy_anima(&anima); 75 gfx_destroy_anima(&anima);
84 return; 76 return;
85 } 77 }
86 case CameraNode: { 78 case CameraNode: {
87 SceneCamera* camera = mem_get_camera(node->camera); 79 Camera* camera = mem_get_camera(node->camera);
88 camera->parent.val = 0;
89 gfx_destroy_camera(&camera); 80 gfx_destroy_camera(&camera);
90 return; 81 return;
91 } 82 }
92 case LightNode: { 83 case LightNode: {
93 Light* light = mem_get_light(node->light); 84 Light* light = mem_get_light(node->light);
94 light->parent.val = 0;
95 gfx_destroy_light(&light); 85 gfx_destroy_light(&light);
96 return; 86 return;
97 } 87 }
@@ -100,13 +90,13 @@ static void free_node_resource(SceneNode* node) {
100 } 90 }
101 case ObjectNode: { 91 case ObjectNode: {
102 SceneObject* object = mem_get_object(node->object); 92 SceneObject* object = mem_get_object(node->object);
103 object->parent.val = 0;
104 gfx_destroy_object(&object); 93 gfx_destroy_object(&object);
105 return; 94 return;
106 } 95 }
107 case LogicalNode: 96 case LogicalNode: {
108 return; // Logical nodes have no resource. 97 return; // Logical nodes have no resource.
109 } 98 }
99 }
110 FAIL("unhandled node type"); 100 FAIL("unhandled node type");
111} 101}
112 102
@@ -170,11 +160,11 @@ Anima* gfx_get_node_anima_mut(SceneNode* node) {
170 NODE_GET(node, anima, AnimaNode); 160 NODE_GET(node, anima, AnimaNode);
171} 161}
172 162
173const SceneCamera* gfx_get_node_camera(const SceneNode* node) { 163const Camera* gfx_get_node_camera(const SceneNode* node) {
174 NODE_GET(node, camera, CameraNode); 164 NODE_GET(node, camera, CameraNode);
175} 165}
176 166
177SceneCamera* gfx_get_node_camera_mut(SceneNode* node) { 167Camera* gfx_get_node_camera_mut(SceneNode* node) {
178 NODE_GET(node, camera, CameraNode); 168 NODE_GET(node, camera, CameraNode);
179} 169}
180 170
diff --git a/src/scene/node_impl.h b/src/scene/node_impl.h
index fb88bd5..15ee232 100644
--- a/src/scene/node_impl.h
+++ b/src/scene/node_impl.h
@@ -4,6 +4,7 @@
4 4
5#include "types.h" 5#include "types.h"
6 6
7#include <math/camera.h>
7#include <math/mat4.h> 8#include <math/mat4.h>
8 9
9/// Scene node. 10/// Scene node.
@@ -12,9 +13,6 @@
12/// together form a strict tree hierarchy and not a more general DAG. 13/// together form a strict tree hierarchy and not a more general DAG.
13typedef struct SceneNode { 14typedef struct SceneNode {
14 NodeType type; 15 NodeType type;
15 // TODO: Inline the actual object here and get rid of the indirection and the
16 // extra pools? The "scene camera" is kind of a useless data structure, for
17 // example.
18 union { 16 union {
19 anima_idx anima; 17 anima_idx anima;
20 camera_idx camera; 18 camera_idx camera;
diff --git a/src/scene/object.c b/src/scene/object.c
index d1f355c..7004ce1 100644
--- a/src/scene/object.c
+++ b/src/scene/object.c
@@ -57,11 +57,7 @@ SceneObject* gfx_make_object(const ObjectDesc* desc) {
57 57
58void gfx_destroy_object(SceneObject** object) { 58void gfx_destroy_object(SceneObject** object) {
59 assert(object); 59 assert(object);
60
61 if (*object) { 60 if (*object) {
62 if ((*object)->parent.val) {
63 gfx_del_node((*object)->parent);
64 }
65 mem_free_object(object); 61 mem_free_object(object);
66 } 62 }
67} 63}
diff --git a/src/scene/object_impl.h b/src/scene/object_impl.h
index e864e53..b7a0752 100644
--- a/src/scene/object_impl.h
+++ b/src/scene/object_impl.h
@@ -19,7 +19,5 @@ typedef struct MeshLink {
19typedef struct SceneObject { 19typedef struct SceneObject {
20 mesh_link_idx mesh_link; /// First MeshLink in the list. 20 mesh_link_idx mesh_link; /// First MeshLink in the list.
21 skeleton_idx skeleton; /// 0 for static objects. 21 skeleton_idx skeleton; /// 0 for static objects.
22 // TODO: Can we just store node indices in nodes, not the contained object? 22 aabb3 box;
23 node_idx parent; /// Parent SceneNode.
24 aabb3 box;
25} SceneObject; 23} SceneObject;
diff --git a/src/scene/scene_graph.h b/src/scene/scene_graph.h
index e7135a4..36c3a98 100644
--- a/src/scene/scene_graph.h
+++ b/src/scene/scene_graph.h
@@ -20,7 +20,7 @@
20#define MEM_GET_INDEX(ITEM) \ 20#define MEM_GET_INDEX(ITEM) \
21 _Generic( \ 21 _Generic( \
22 (ITEM), \ 22 (ITEM), \
23 SceneCamera *: mem_get_camera_index, \ 23 Camera *: mem_get_camera_index, \
24 Material *: mem_get_material_index, \ 24 Material *: mem_get_material_index, \
25 Mesh *: mem_get_mesh_index, \ 25 Mesh *: mem_get_mesh_index, \
26 MeshLink *: mem_get_mesh_link_index, \ 26 MeshLink *: mem_get_mesh_link_index, \