mirror of
https://github.com/storytold/storyteller-bevy.git
synced 2026-10-17 00:13:17 +00:00
Tag skeletal joints, draw skeleton in debug mode
This commit is contained in:
@@ -192,7 +192,7 @@ export class AppElement extends LitElement {
|
||||
try {
|
||||
studio.startViewer(
|
||||
"base-human-female",
|
||||
"meadow_4k",
|
||||
"test_scene",
|
||||
"#studio_canvas",
|
||||
"Storyteller Studio",
|
||||
new ViewportSize(width, height),
|
||||
|
||||
+22
-1
@@ -7,6 +7,7 @@ use bevy_mod_picking::debug::DebugPickingMode;
|
||||
use crate::{
|
||||
camera_controller::{CameraController, CameraMotionSystem},
|
||||
input::{Action, InputAction, Lifecycle},
|
||||
scene::SkeletalJoint,
|
||||
MainCamera,
|
||||
};
|
||||
|
||||
@@ -38,7 +39,7 @@ impl Plugin for DebugPlugin {
|
||||
toggle_debug_mode,
|
||||
update_debug_picking_mode.run_if(resource_changed::<DebugMode>()),
|
||||
update_gizmo_line_thickness,
|
||||
(draw_world_axes, draw_debug_points)
|
||||
(draw_world_axes, draw_debug_points, draw_skeletal_joints)
|
||||
.after(CameraMotionSystem)
|
||||
.run_if(is_debug_mode),
|
||||
),
|
||||
@@ -108,6 +109,26 @@ fn draw_debug_points(
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_skeletal_joints(
|
||||
mut gizmos: Gizmos,
|
||||
q_joints: Query<(&GlobalTransform, Option<&Parent>), With<SkeletalJoint>>,
|
||||
) {
|
||||
for (world_xform, parent) 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()) {
|
||||
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);
|
||||
} else {
|
||||
gizmos.sphere(xlation, rotation, 0.01, Color::BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[allow(dead_code)]
|
||||
pub fn write_mat3(w: &mut impl fmt::Write, m: &Mat3) -> fmt::Result {
|
||||
|
||||
+21
-6
@@ -9,7 +9,7 @@ use bevy::{
|
||||
math::{vec2, vec3},
|
||||
pbr::ShadowFilteringMethod,
|
||||
prelude::*,
|
||||
render::primitives::Aabb,
|
||||
render::{mesh::skinning::SkinnedMesh, primitives::Aabb},
|
||||
scene::InstanceId,
|
||||
};
|
||||
|
||||
@@ -107,6 +107,9 @@ pub struct LoadSceneEvent(pub String);
|
||||
#[derive(Component)]
|
||||
pub struct SceneElement;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct SkeletalJoint;
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct SceneRoot;
|
||||
|
||||
@@ -245,18 +248,30 @@ fn tag_scene_elements(
|
||||
// leafy parts of a plant. Here we only want to tag the elements that a user
|
||||
// might want to individually address when arranging or animating a scene.
|
||||
q_named_non_primitives: Query<&Name, Without<Handle<Mesh>>>,
|
||||
q_skinned_meshes: Query<&SkinnedMesh>,
|
||||
) {
|
||||
let gltf = ra_gltfs.get(&r_active_scene.source).unwrap();
|
||||
|
||||
for ent in r_scene_spawner.iter_instance_entities(**r_active_scene) {
|
||||
let Ok(name) = q_named_non_primitives.get(ent) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
for (ent, name) in r_scene_spawner
|
||||
.iter_instance_entities(**r_active_scene)
|
||||
.filter_map(|ent| match q_named_non_primitives.get(ent) {
|
||||
Ok(name) => Some((ent, name)),
|
||||
_ => None,
|
||||
})
|
||||
{
|
||||
if gltf.named_nodes.contains_key(&**name) {
|
||||
cmd.entity(ent).insert(SceneElement);
|
||||
}
|
||||
}
|
||||
|
||||
for skinned_mesh in r_scene_spawner
|
||||
.iter_instance_entities(**r_active_scene)
|
||||
.filter_map(|ent| q_skinned_meshes.get(ent).ok())
|
||||
{
|
||||
for &joint in skinned_mesh.joints.iter() {
|
||||
cmd.entity(joint).insert(SkeletalJoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_main_scene_light(
|
||||
|
||||
Reference in New Issue
Block a user