summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-02-17 20:19:46 -0800
committer3gg <3gg@shellblade.net>2024-02-17 20:19:46 -0800
commit90d9d72530a893872e2413139410f5fcd48cb387 (patch)
treef1c1402ade39b436d4ede5ed2655edf5dab0e8d5
parent4f1d07f9a873ca3b6670fa0393483034e4fdf1e4 (diff)
Remove joint nodes after the model anima is loaded.
-rw-r--r--gfx/src/asset/model.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/gfx/src/asset/model.c b/gfx/src/asset/model.c
index 73ce731..05e6e91 100644
--- a/gfx/src/asset/model.c
+++ b/gfx/src/asset/model.c
@@ -986,7 +986,7 @@ static bool load_meshes(
986 const cgltf_buffer_view* view = accessor->buffer_view; 986 const cgltf_buffer_view* view = accessor->buffer_view;
987 const cgltf_size offset = accessor->offset + view->offset; 987 const cgltf_size offset = accessor->offset + view->offset;
988 const cgltf_size buffer_index = view->buffer - data->buffers; 988 const cgltf_size buffer_index = view->buffer - data->buffers;
989 989
990 assert(buffer_index < data->buffers_count); 990 assert(buffer_index < data->buffers_count);
991 Buffer* buffer = buffers[buffer_index]; 991 Buffer* buffer = buffers[buffer_index];
992 992
@@ -1492,6 +1492,66 @@ static void load_nodes(
1492 } // SceneNode. 1492 } // SceneNode.
1493} 1493}
1494 1494
1495/// Remove joint nodes from the Gfx Scene.
1496///
1497/// Joint nodes are not needed because joints are packed into the Anima.
1498static void remove_joint_nodes(
1499 const cgltf_data* data, SceneNode** scene_nodes) {
1500 assert(data);
1501 assert(scene_nodes);
1502
1503 // This works assuming the joint nodes are contiguous. Contiguity is checked
1504 // when loading skins. See load_skins().
1505 size_t min_joint_index = (size_t)-1;
1506 size_t max_joint_index = 0;
1507
1508 // First get the minimum and maximum indices of all joint nodes.
1509 for (cgltf_size s = 0; s < data->skins_count; ++s) {
1510 const cgltf_skin* skin = &data->skins[s];
1511
1512 for (cgltf_size j = 0; j < skin->joints_count; ++j) {
1513 // Joint is an index/pointer into the nodes array.
1514 const cgltf_size joint_index = skin->joints[j] - data->nodes;
1515 assert(joint_index < data->nodes_count);
1516
1517 if (joint_index < min_joint_index) {
1518 min_joint_index = joint_index;
1519 }
1520 if (joint_index > max_joint_index) {
1521 max_joint_index = joint_index;
1522 }
1523 }
1524 }
1525
1526 assert(min_joint_index < data->nodes_count);
1527 assert(max_joint_index < data->nodes_count);
1528
1529 // Now walk over the joint nodes. If a joint's parent is itself not a joint
1530 // node, then that joint is a root of a joint hierarchy (skins in glTF may
1531 // have multiple roots). In such case, delete the root joint recursively.
1532 for (cgltf_size s = 0; s < data->skins_count; ++s) {
1533 const cgltf_skin* skin = &data->skins[s];
1534
1535 for (cgltf_size j = 0; j < skin->joints_count; ++j) {
1536 // Joint is an index/pointer into the nodes array.
1537 const cgltf_size joint_index = skin->joints[j] - data->nodes;
1538 assert(joint_index < data->nodes_count);
1539
1540 const cgltf_node* joint = &data->nodes[joint_index];
1541
1542 // Parent node index.
1543 const cgltf_size parent_index = joint->parent - data->nodes;
1544 assert(parent_index < data->nodes_count);
1545
1546 // If the parent is not a joint node, recursively delete this joint node.
1547 if ((parent_index < min_joint_index) ||
1548 (parent_index > max_joint_index)) {
1549 gfx_destroy_node(&scene_nodes[joint_index]);
1550 }
1551 }
1552 }
1553}
1554
1495/// Load all scenes from the glTF file. 1555/// Load all scenes from the glTF file.
1496/// 1556///
1497/// If the scene is loaded from memory, set filepath = null. 1557/// If the scene is loaded from memory, set filepath = null.
@@ -1629,7 +1689,11 @@ static Model* load_scene(
1629 // The root node becomes the root of all scene nodes. 1689 // The root node becomes the root of all scene nodes.
1630 load_nodes(data, root_node, scene_objects, scene_cameras, anima, scene_nodes); 1690 load_nodes(data, root_node, scene_objects, scene_cameras, anima, scene_nodes);
1631 1691
1632 // TODO: Clean up scene nodes that correspond to joints in the glTF. 1692 // Clean up scene nodes that correspond to joints in the glTF. These are
1693 // not needed anymore.
1694 if (data->skins_count > 0) {
1695 remove_joint_nodes(data, scene_nodes);
1696 }
1633 1697
1634 model = gfx_make_model(root_node); 1698 model = gfx_make_model(root_node);
1635 1699