Spawn disembodied BVH skeleton

This commit is contained in:
Danny McGee
2023-12-21 18:59:05 -05:00
parent 1bfb81f13d
commit 5164e85ff5
3 changed files with 54 additions and 14 deletions
+9 -3
View File
@@ -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::<Vec<_>>();
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 })
+6 -6
View File
@@ -111,20 +111,20 @@ fn draw_debug_points(
fn draw_skeletal_joints(
mut gizmos: Gizmos,
q_joints: Query<(&GlobalTransform, Option<&Parent>), With<SkeletalJoint>>,
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);
}
}
}
+39 -5
View File
@@ -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<AssetServer>) {
// TODO
fn spawn_test_bvh(
mut _cmd: Commands,
mut cmd: Commands,
mut er_bvh_events: EventReader<AssetEvent<Bvh>>,
r_bvh: Res<TestBvh>,
ra_bvh: Res<Assets<Bvh>>,
@@ -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<Entity>) {
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<AssetServer>,
@@ -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));
}
}
}