diff --git a/studio/src/bvh/loader.rs b/studio/src/bvh/loader.rs index 4565dee..4df8c49 100644 --- a/studio/src/bvh/loader.rs +++ b/studio/src/bvh/loader.rs @@ -30,9 +30,15 @@ impl AssetLoader for BvhLoader { // FIXME: This is algorithmically terrible let bvh = studio_bvh::from_bytes(&buf).anyhow()?; let all_joints = bvh.joints().map(|j| j.data().clone()).collect::>(); - let joints = all_joints - .iter() - .map(|joint| joint.clone().into_bvh_joint(&all_joints)) + let joints = bvh + .joints() + .filter_map(|joint| { + if joint.is_root() { + Some(joint.data().clone().into_bvh_joint(&all_joints)) + } else { + None + } + }) .collect(); Ok(Bvh { joints }) diff --git a/studio/src/debug.rs b/studio/src/debug.rs index 03bc7a5..d89541c 100644 --- a/studio/src/debug.rs +++ b/studio/src/debug.rs @@ -111,20 +111,20 @@ fn draw_debug_points( fn draw_skeletal_joints( mut gizmos: Gizmos, - q_joints: Query<(&GlobalTransform, Option<&Parent>), With>, + q_joints: Query<(&GlobalTransform, Option<&Parent>, &SkeletalJoint)>, ) { - for (world_xform, parent) in q_joints.iter() { + for (world_xform, parent, joint) in q_joints.iter() { let (_, rotation, xlation) = world_xform.to_scale_rotation_translation(); - if let Some((parent_xform, _)) = parent.and_then(|parent| q_joints.get(**parent).ok()) { + if let Some((parent_xform, _, _)) = parent.and_then(|parent| q_joints.get(**parent).ok()) { let parent_xlation = parent_xform.translation(); let bone_len = Vec3::distance(xlation, parent_xlation); let joint_radius = f32::min(0.01, bone_len / 6.); - gizmos.sphere(xlation, rotation, joint_radius, Color::BLACK); - gizmos.line(xlation, parent_xlation, Color::BLACK); + gizmos.sphere(xlation, rotation, joint_radius, joint.0); + gizmos.line(xlation, parent_xlation, joint.0); } else { - gizmos.sphere(xlation, rotation, 0.01, Color::BLACK); + gizmos.sphere(xlation, rotation, 0.01, joint.0); } } } diff --git a/studio/src/scene.rs b/studio/src/scene.rs index 0965549..8c25223 100644 --- a/studio/src/scene.rs +++ b/studio/src/scene.rs @@ -17,7 +17,7 @@ use bevy::{ use wasm_bindgen::prelude::wasm_bindgen; use crate::{ - bvh::Bvh, + bvh::{Bvh, BvhJoint}, camera_controller::{CameraController, CameraControllerBundle}, debug::DebugPoint, math::{Combinable, Extrema}, @@ -110,7 +110,7 @@ pub struct LoadSceneEvent(pub String); pub struct SceneElement; #[derive(Component)] -pub struct SkeletalJoint; +pub struct SkeletalJoint(pub Color); #[derive(Component)] pub struct SceneRoot; @@ -155,7 +155,7 @@ fn initialize(mut cmd: Commands, r_assets: Res) { // TODO fn spawn_test_bvh( - mut _cmd: Commands, + mut cmd: Commands, mut er_bvh_events: EventReader>, r_bvh: Res, ra_bvh: Res>, @@ -163,11 +163,45 @@ fn spawn_test_bvh( for event in er_bvh_events.read() { if matches!(event, AssetEvent::LoadedWithDependencies { .. }) { let bvh = ra_bvh.get(&**r_bvh).unwrap(); - info!("{bvh:#?}"); + for joint in bvh.joints.iter() { + let scale = Vec3::splat(0.01); + let offset = vec3(0., 0.849, -0.024); + + let mut parent = cmd.spawn(( + Name::new("BVH Skeleton"), + SpatialBundle::from_transform(Transform { + rotation: default(), + translation: offset, + scale, + }), + )); + let parent_ent = parent.id(); + + spawn_joint(parent.commands(), joint, Some(parent_ent)); + } } } } +// TODO +fn spawn_joint(cmd: &mut Commands, joint: &BvhJoint, parent: Option) { + let mut spawned = cmd.spawn(( + Name::new(joint.name.clone()), + SpatialBundle::from_transform(joint.transform), + SceneElement, + SkeletalJoint(Color::CYAN), + )); + let spawned_ent = spawned.id(); + + if let Some(parent) = parent { + spawned.set_parent(parent); + } + + for child in joint.children.iter() { + spawn_joint(spawned.commands(), child, Some(spawned_ent)); + } +} + fn init_scene_loading( mut cmd: Commands, assets: Res, @@ -298,7 +332,7 @@ fn tag_scene_elements( cmd.entity(ent).insert(NoFrustumCulling); for &joint in skinned_mesh.joints.iter() { - cmd.entity(joint).insert(SkeletalJoint); + cmd.entity(joint).insert(SkeletalJoint(Color::BLACK)); } } }