mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-17 00:13:17 +00:00
Spawn disembodied BVH skeleton
This commit is contained in:
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user