diff options
| author | 3gg <3gg@shellblade.net> | 2025-10-30 17:21:22 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-10-30 17:21:25 -0700 |
| commit | 440b292c39162284a447b34d3a692143af9fbc87 (patch) | |
| tree | b5f0adf047651a56eb74ba7b92fdf6ebe2bbc635 /src/scene | |
| parent | 643382dfd364a193686201e1c82b6fe7f351f068 (diff) | |
- Replace SceneCamera with Camera.
- Remove backpointer from scene types to node to decouple underlying types from the scene graph.
Diffstat (limited to 'src/scene')
| -rw-r--r-- | src/scene/animation.c | 10 | ||||
| -rw-r--r-- | src/scene/animation_impl.h | 30 | ||||
| -rw-r--r-- | src/scene/camera.c | 28 | ||||
| -rw-r--r-- | src/scene/camera_impl.h | 12 | ||||
| -rw-r--r-- | src/scene/model_impl.h | 1 | ||||
| -rw-r--r-- | src/scene/node.c | 32 | ||||
| -rw-r--r-- | src/scene/node_impl.h | 4 | ||||
| -rw-r--r-- | src/scene/object.c | 4 | ||||
| -rw-r--r-- | src/scene/object_impl.h | 4 | ||||
| -rw-r--r-- | src/scene/scene_graph.h | 2 |
10 files changed, 36 insertions, 91 deletions
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 | ||
| 17 | typedef struct Buffer Buffer; | 16 | typedef 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. |
| 26 | typedef struct Joint { | 25 | typedef 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. |
| 36 | typedef struct Skeleton { | 35 | typedef 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. |
| 43 | typedef struct Keyframe { | 42 | typedef 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. |
| 52 | typedef struct Channel { | 51 | typedef 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). |
| 91 | typedef struct Anima { | 90 | typedef 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 | ||
| 8 | SceneCamera* gfx_make_camera() { | 8 | Camera* 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 | ||
| 18 | void gfx_destroy_camera(SceneCamera** camera) { | 16 | void 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 | |||
| 28 | void gfx_set_camera_camera(SceneCamera* scene_camera, Camera* camera) { | ||
| 29 | assert(scene_camera); | ||
| 30 | assert(camera); | ||
| 31 | scene_camera->camera = *camera; | ||
| 32 | } | ||
| 33 | |||
| 34 | Camera* 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 | |||
| 9 | typedef 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. |
| 8 | typedef struct Model { | 8 | typedef 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 | ||
| 22 | SceneNode* gfx_make_node() { | 22 | SceneNode* 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 | ||
| 37 | SceneNode* gfx_make_camera_node(SceneCamera* camera) { | 36 | SceneNode* 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) { | |||
| 74 | static void free_node_resource(SceneNode* node) { | 69 | static 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 | ||
| 173 | const SceneCamera* gfx_get_node_camera(const SceneNode* node) { | 163 | const Camera* gfx_get_node_camera(const SceneNode* node) { |
| 174 | NODE_GET(node, camera, CameraNode); | 164 | NODE_GET(node, camera, CameraNode); |
| 175 | } | 165 | } |
| 176 | 166 | ||
| 177 | SceneCamera* gfx_get_node_camera_mut(SceneNode* node) { | 167 | Camera* 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. |
| 13 | typedef struct SceneNode { | 14 | typedef 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 | ||
| 58 | void gfx_destroy_object(SceneObject** object) { | 58 | void 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 { | |||
| 19 | typedef struct SceneObject { | 19 | typedef 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, \ |
