diff options
| -rw-r--r-- | include/gfx/render/renderer.h | 14 | ||||
| -rw-r--r-- | include/gfx/scene/animation.h | 1 | ||||
| -rw-r--r-- | include/gfx/scene/camera.h | 15 | ||||
| -rw-r--r-- | include/gfx/scene/node.h | 10 | ||||
| -rw-r--r-- | src/asset/asset_cache.c | 1 | ||||
| -rw-r--r-- | src/asset/model.c | 34 | ||||
| -rw-r--r-- | src/memory.c | 13 | ||||
| -rw-r--r-- | src/memory.h | 10 | ||||
| -rw-r--r-- | src/render/llr.c | 3 | ||||
| -rw-r--r-- | src/render/llr_impl.h | 1 | ||||
| -rw-r--r-- | src/render/renderer.c | 13 | ||||
| -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 | 
21 files changed, 80 insertions, 162 deletions
| diff --git a/include/gfx/render/renderer.h b/include/gfx/render/renderer.h index 1da74eb..6cebe50 100644 --- a/include/gfx/render/renderer.h +++ b/include/gfx/render/renderer.h | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | #pragma once | 1 | #pragma once | 
| 2 | 2 | ||
| 3 | #include <math/defs.h> | 3 | #include <math/defs.h> | 
| 4 | #include <math/fwd.h> | ||
| 4 | 5 | ||
| 5 | typedef struct GfxCore GfxCore; | 6 | typedef struct GfxCore GfxCore; | 
| 6 | typedef struct Scene Scene; | 7 | typedef struct Scene Scene; | 
| 7 | typedef struct SceneCamera SceneCamera; | ||
| 8 | 8 | ||
| 9 | typedef struct Renderer Renderer; | 9 | typedef struct Renderer Renderer; | 
| 10 | 10 | ||
| @@ -17,13 +17,13 @@ typedef enum RenderSceneMode { | |||
| 17 | } RenderSceneMode; | 17 | } RenderSceneMode; | 
| 18 | 18 | ||
| 19 | typedef struct RenderSceneParams { | 19 | typedef struct RenderSceneParams { | 
| 20 | RenderSceneMode mode; | 20 | RenderSceneMode mode; | 
| 21 | const Scene* scene; | 21 | const Scene* scene; | 
| 22 | const SceneCamera* camera; | 22 | const Camera* camera; | 
| 23 | } RenderSceneParams; | 23 | } RenderSceneParams; | 
| 24 | 24 | ||
| 25 | /// Render the scene. | 25 | /// Render the scene. | 
| 26 | void gfx_render_scene(Renderer*, const RenderSceneParams*); | 26 | void gfx_render_scene(Renderer*, const RenderSceneParams*); | 
| 27 | 27 | ||
| 28 | /// Update the scene. | 28 | /// Update the scene. | 
| 29 | void gfx_update(Scene*, const SceneCamera*, R t); | 29 | void gfx_update(Scene*, const Camera*, R t); | 
| diff --git a/include/gfx/scene/animation.h b/include/gfx/scene/animation.h index b55e575..11d8984 100644 --- a/include/gfx/scene/animation.h +++ b/include/gfx/scene/animation.h | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | // TODO: Move outside of scene/ | ||
| 1 | #pragma once | 2 | #pragma once | 
| 2 | 3 | ||
| 3 | #include <gfx/sizes.h> | 4 | #include <gfx/sizes.h> | 
| diff --git a/include/gfx/scene/camera.h b/include/gfx/scene/camera.h index 99d83fe..873f780 100644 --- a/include/gfx/scene/camera.h +++ b/include/gfx/scene/camera.h | |||
| @@ -4,19 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | typedef struct SceneNode SceneNode; | 5 | typedef struct SceneNode SceneNode; | 
| 6 | 6 | ||
| 7 | typedef struct SceneCamera SceneCamera; | 7 | typedef struct Camera Camera; | 
| 8 | 8 | ||
| 9 | /// Create a new camera. | 9 | /// Create a new camera. | 
| 10 | SceneCamera* gfx_make_camera(); | 10 | Camera* gfx_make_camera(); | 
| 11 | 11 | ||
| 12 | /// Destroy the camera. | 12 | /// Destroy the camera. | 
| 13 | /// | 13 | void gfx_destroy_camera(Camera**); | 
| 14 | /// The camera is conveniently removed from the scene graph and its parent scene | ||
| 15 | /// node is destroyed. | ||
| 16 | void gfx_destroy_camera(SceneCamera**); | ||
| 17 | |||
| 18 | /// Set the scene camera's math camera. | ||
| 19 | void gfx_set_camera_camera(SceneCamera* scene_camera, Camera* camera); | ||
| 20 | |||
| 21 | /// Get the scene camera's math camera. | ||
| 22 | Camera* gfx_get_camera_camera(SceneCamera*); | ||
| diff --git a/include/gfx/scene/node.h b/include/gfx/scene/node.h index 20b97e2..215bbda 100644 --- a/include/gfx/scene/node.h +++ b/include/gfx/scene/node.h | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | #include <math/mat4.h> | 4 | #include <math/mat4.h> | 
| 5 | 5 | ||
| 6 | typedef struct Anima Anima; | 6 | typedef struct Anima Anima; | 
| 7 | typedef struct Camera Camera; | ||
| 7 | typedef struct Light Light; | 8 | typedef struct Light Light; | 
| 8 | typedef struct Model Model; | 9 | typedef struct Model Model; | 
| 9 | typedef struct SceneCamera SceneCamera; | ||
| 10 | typedef struct SceneObject SceneObject; | 10 | typedef struct SceneObject SceneObject; | 
| 11 | 11 | ||
| 12 | /// Scene node type. | 12 | /// Scene node type. | 
| @@ -33,13 +33,13 @@ typedef struct SceneNode SceneNode; | |||
| 33 | /// | 33 | /// | 
| 34 | /// This node does not contain any camera, light, object, etc. and exists simply | 34 | /// This node does not contain any camera, light, object, etc. and exists simply | 
| 35 | /// as a logical and spatial construct. | 35 | /// as a logical and spatial construct. | 
| 36 | SceneNode* gfx_make_node(); | 36 | SceneNode* gfx_make_node(void); | 
| 37 | 37 | ||
| 38 | /// Create an anima node. | 38 | /// Create an anima node. | 
| 39 | SceneNode* gfx_make_anima_node(Anima*); | 39 | SceneNode* gfx_make_anima_node(Anima*); | 
| 40 | 40 | ||
| 41 | /// Create a new camera node. | 41 | /// Create a new camera node. | 
| 42 | SceneNode* gfx_make_camera_node(SceneCamera*); | 42 | SceneNode* gfx_make_camera_node(Camera*); | 
| 43 | 43 | ||
| 44 | /// Create a new light node. | 44 | /// Create a new light node. | 
| 45 | SceneNode* gfx_make_light_node(Light*); | 45 | SceneNode* gfx_make_light_node(Light*); | 
| @@ -73,8 +73,8 @@ Anima* gfx_get_node_anima_mut(SceneNode*); | |||
| 73 | /// Get the node's camera. | 73 | /// Get the node's camera. | 
| 74 | /// | 74 | /// | 
| 75 | /// The node must be of type CameraNode. | 75 | /// The node must be of type CameraNode. | 
| 76 | const SceneCamera* gfx_get_node_camera(const SceneNode* node); | 76 | const Camera* gfx_get_node_camera(const SceneNode* node); | 
| 77 | SceneCamera* gfx_get_node_camera_mut(SceneNode* node); | 77 | Camera* gfx_get_node_camera_mut(SceneNode* node); | 
| 78 | 78 | ||
| 79 | /// Get the node's light. | 79 | /// Get the node's light. | 
| 80 | /// | 80 | /// | 
| 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. | 
| 1556 | static void load_nodes( | 1556 | static 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 | ||
| 16 | DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS) | 17 | DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS) | 
| 17 | DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS) | 18 | DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS) | 
| 18 | DEF_MEMPOOL(camera_pool, SceneCamera, GFX_MAX_NUM_CAMERAS) | 19 | DEF_MEMPOOL(camera_pool, Camera, GFX_MAX_NUM_CAMERAS) | 
| 19 | DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS) | 20 | DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS) | 
| 20 | DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS) | 21 | DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS) | 
| 21 | DEF_MEMPOOL(mesh_pool, Mesh, GFX_MAX_NUM_MESHES) | 22 | DEF_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 | ||
| 59 | void scene_mem_init() { | 60 | void 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 | ||
| 89 | void scene_mem_destroy() { | 90 | void 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 | ||
| 165 | DEF_MEMORY(anima, Anima) | 166 | DEF_MEMORY(anima, Anima) | 
| 166 | DEF_MEMORY(animation, Animation) | 167 | DEF_MEMORY(animation, Animation) | 
| 167 | DEF_MEMORY(camera, SceneCamera) | 168 | DEF_MEMORY(camera, Camera) | 
| 168 | DEF_MEMORY(light, Light) | 169 | DEF_MEMORY(light, Light) | 
| 169 | DEF_MEMORY(material, Material) | 170 | DEF_MEMORY(material, Material) | 
| 170 | DEF_MEMORY(mesh, Mesh) | 171 | DEF_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 | ||
| 6 | typedef 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". | 
| 10 | void scene_mem_init(); | 12 | void scene_mem_init(void); | 
| 11 | 13 | ||
| 12 | /// Destroy the scene memory and all allocated objects. | 14 | /// Destroy the scene memory and all allocated objects. | 
| 13 | void scene_mem_destroy(); | 15 | void 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 | ||
| 28 | DECL_MEMORY(anima, Anima) | 30 | DECL_MEMORY(anima, Anima) | 
| 29 | DECL_MEMORY(animation, Animation) | 31 | DECL_MEMORY(animation, Animation) | 
| 30 | DECL_MEMORY(camera, SceneCamera) | 32 | DECL_MEMORY(camera, Camera) | 
| 31 | DECL_MEMORY(light, Light) | 33 | DECL_MEMORY(light, Light) | 
| 32 | DECL_MEMORY(material, Material) | 34 | DECL_MEMORY(material, Material) | 
| 33 | DECL_MEMORY(mesh, Mesh) | 35 | DECL_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) { | |||
| 46 | void gfx_destroy_light(Light** light) { | 46 | void 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 | ||
| 40 | typedef struct Material { | 39 | typedef 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 | ||
| 215 | static void update_rec(SceneNode* node, const SceneCamera* camera, R t) { | 214 | static 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 | ||
| 240 | void gfx_update(Scene* scene, const SceneCamera* camera, R t) { | 239 | void 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 | ||
| 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, \ | 
