From b9118becfc33173a4f829cad9bbee64516eeae98 Mon Sep 17 00:00:00 2001 From: Jay Christy Date: Sun, 22 Oct 2023 15:22:09 -0400 Subject: [PATCH 1/4] added ugly exclusive grabbing --- examples/demo/src/main.rs | 79 +++++++++++++++++++++++++----------- src/xr_input/interactions.rs | 10 +++++ 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/examples/demo/src/main.rs b/examples/demo/src/main.rs index 37b5490..5841c71 100644 --- a/examples/demo/src/main.rs +++ b/examples/demo/src/main.rs @@ -2,10 +2,10 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, log::info, prelude::{ - default, shape, App, Assets, Color, Commands, Component, Event, EventReader, EventWriter, - GlobalTransform, IntoSystemConfigs, IntoSystemSetConfigs, Mesh, PbrBundle, PostUpdate, - Query, Res, ResMut, Resource, SpatialBundle, StandardMaterial, Startup, Transform, Update, - With, Without, + default, shape, App, Assets, Color, Commands, Component, Entity, Event, EventReader, + EventWriter, GlobalTransform, IntoSystemConfigs, IntoSystemSetConfigs, Mesh, PbrBundle, + PostUpdate, Query, Res, ResMut, Resource, SpatialBundle, StandardMaterial, Startup, + Transform, Update, With, Without, }, time::{Time, Timer}, transform::TransformSystem, @@ -18,7 +18,7 @@ use bevy_openxr::{ interactions::{ draw_interaction_gizmos, draw_socket_gizmos, interactions, socket_interactions, update_interactable_states, InteractionEvent, Touched, XRDirectInteractor, - XRInteractable, XRInteractableState, XRInteractorState, XRRayInteractor, + XRInteractable, XRInteractableState, XRInteractorState, XRSelection, }, oculus_touch::OculusController, prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig}, @@ -79,8 +79,7 @@ fn main() { bevy::time::TimerMode::Once, ))) .add_systems(Update, request_cube_spawn) - .add_systems(Update, cube_spawner.after(request_cube_spawn)) - ; + .add_systems(Update, cube_spawner.after(request_cube_spawn)); //configure rapier sets app.configure_sets( @@ -121,6 +120,7 @@ fn spawn_controllers_example(mut commands: Commands) { SpatialBundle::default(), XRDirectInteractor, XRInteractorState::default(), + XRSelection::default(), )); //right hand commands.spawn(( @@ -130,6 +130,7 @@ fn spawn_controllers_example(mut commands: Commands) { SpatialBundle::default(), XRDirectInteractor, XRInteractorState::default(), + XRSelection::default(), )); } @@ -247,12 +248,18 @@ pub struct Grabbable; pub fn update_grabbables( mut events: EventReader, mut grabbable_query: Query<( + Entity, &mut Transform, With, Without, Option<&mut RigidBody>, )>, - interactor_query: Query<(&GlobalTransform, &XRInteractorState, Without)>, + mut interactor_query: Query<( + &GlobalTransform, + &XRInteractorState, + &mut XRSelection, + Without, + )>, ) { //so basically the idea is to try all the events? for event in events.read() { @@ -261,24 +268,48 @@ pub fn update_grabbables( Ok(mut grabbable_transform) => { // info!("we got a grabbable"); //now we need the location of our interactor - match interactor_query.get(event.interactor) { - Ok(interactor_transform) => { - match interactor_transform.1 { - XRInteractorState::Idle => match grabbable_transform.3 { - Some(mut thing) => { - *thing = RigidBody::Dynamic; - } - None => (), - }, - XRInteractorState::Selecting => { - // info!("its a direct interactor?"); - match grabbable_transform.3 { - Some(mut thing) => { - *thing = RigidBody::KinematicPositionBased; + match interactor_query.get_mut(event.interactor) { + Ok(mut interactor_transform) => { + match *interactor_transform.2 { + XRSelection::Empty => { + match interactor_transform.1 { + XRInteractorState::Idle => match grabbable_transform.4 { + Some(mut thing) => { + *thing = RigidBody::Dynamic; + *interactor_transform.2 = XRSelection::Empty; + } + None => (), + }, + XRInteractorState::Selecting => { + // info!("its a direct interactor?"); + match grabbable_transform.4 { + Some(mut thing) => { + *thing = RigidBody::KinematicPositionBased; + *interactor_transform.2 = + XRSelection::Full(grabbable_transform.0); + } + None => (), + } + *grabbable_transform.1 = + interactor_transform.0.compute_transform(); } - None => (), } - *grabbable_transform.0 = interactor_transform.0.compute_transform(); + } + XRSelection::Full(ent) => { + info!("nah bro we holding something"); + match grabbable_transform.0 == ent { + true => { + *grabbable_transform.1 = + interactor_transform.0.compute_transform(); + } + false => {} + } + match interactor_transform.1 { + XRInteractorState::Idle => { + *interactor_transform.2 = XRSelection::Empty + } + XRInteractorState::Selecting => {} + } } } } diff --git a/src/xr_input/interactions.rs b/src/xr_input/interactions.rs index 9660839..5d7463b 100644 --- a/src/xr_input/interactions.rs +++ b/src/xr_input/interactions.rs @@ -42,6 +42,16 @@ impl Default for XRInteractorState { XRInteractorState::Idle } } +#[derive(Component)] +pub enum XRSelection { + Empty, + Full(Entity) +} +impl Default for XRSelection { + fn default() -> Self { + XRSelection::Empty + } +} #[derive(Component)] pub struct XRInteractable; From e5679b4e471d71309bf778ceb4e64aae87289ee5 Mon Sep 17 00:00:00 2001 From: Jay Christy Date: Tue, 24 Oct 2023 16:48:56 -0400 Subject: [PATCH 2/4] working right thumb metacarpal --- examples/demo/src/main.rs | 164 +++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) diff --git a/examples/demo/src/main.rs b/examples/demo/src/main.rs index 5841c71..d31adac 100644 --- a/examples/demo/src/main.rs +++ b/examples/demo/src/main.rs @@ -5,7 +5,7 @@ use bevy::{ default, shape, App, Assets, Color, Commands, Component, Entity, Event, EventReader, EventWriter, GlobalTransform, IntoSystemConfigs, IntoSystemSetConfigs, Mesh, PbrBundle, PostUpdate, Query, Res, ResMut, Resource, SpatialBundle, StandardMaterial, Startup, - Transform, Update, With, Without, + Transform, Update, Vec3, With, Without, }, time::{Time, Timer}, transform::TransformSystem, @@ -15,6 +15,7 @@ use bevy_openxr::{ resources::{XrFrameState, XrInstance, XrSession}, xr_input::{ debug_gizmos::OpenXrDebugRenderer, + hand::{HandBone, HandInputDebugRenderer, HandResource, HandsResource, OpenXrHandInput}, interactions::{ draw_interaction_gizmos, draw_socket_gizmos, interactions, socket_interactions, update_interactable_states, InteractionEvent, Touched, XRDirectInteractor, @@ -48,7 +49,7 @@ fn main() { .add_plugins(OpenXrDebugRenderer) //rapier goes here .add_plugins(RapierPhysicsPlugin::::default().with_default_system_setup(false)) - // .add_plugins(RapierDebugRenderPlugin::default()) + .add_plugins(RapierDebugRenderPlugin::default()) //lets setup the starting scene .add_systems(Startup, setup_scene) .add_systems(Startup, spawn_controllers_example) //you need to spawn controllers or it crashes TODO:: Fix this @@ -79,7 +80,14 @@ fn main() { bevy::time::TimerMode::Once, ))) .add_systems(Update, request_cube_spawn) - .add_systems(Update, cube_spawner.after(request_cube_spawn)); + .add_systems(Update, cube_spawner.after(request_cube_spawn)) + //test capsule + .add_systems(Startup, spawn_capsule) + //physics hands + .add_plugins(OpenXrHandInput) + .add_plugins(HandInputDebugRenderer) + .add_systems(Startup, spawn_physics_hands) + .add_systems(Update, update_physics_hands); //configure rapier sets app.configure_sets( @@ -134,6 +142,156 @@ fn spawn_controllers_example(mut commands: Commands) { )); } +fn spawn_capsule( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, +) { + commands.spawn(( + PbrBundle { + mesh: meshes.add(Mesh::from(shape::Capsule { + radius: 0.033, + depth: 0.115, + ..default() + })), + material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), + transform: Transform::from_xyz(0.0, 2.0, 0.0), + ..default() + }, + // Collider::capsule_y(0.0575, 0.034), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + 0.034, + ), + RigidBody::Dynamic, + )); +} + +#[derive(Component, PartialEq)] +pub enum PhysicsHandBone { + Palm, + Wrist, + ThumbMetacarpal, + ThumbProximal, + ThumbDistal, + ThumbTip, + IndexMetacarpal, + IndexProximal, + IndexIntermediate, + IndexDistal, + IndexTip, + MiddleMetacarpal, + MiddleProximal, + MiddleIntermediate, + MiddleDistal, + MiddleTip, + RingMetacarpal, + RingProximal, + RingIntermediate, + RingDistal, + RingTip, + LittleMetacarpal, + LittleProximal, + LittleIntermediate, + LittleDistal, + LittleTip, +} +#[derive(Component, PartialEq)] +pub enum BoneInitState { + True, + False, +} + +fn spawn_physics_hands(mut commands: Commands) { + //lets just do the Right ThumbMetacarpal for now + //i dont understand the groups yet + let self_group = Group::GROUP_1; + let interaction_group = Group::ALL; + let radius = 0.010; + //spawn the thing + commands.spawn(( + SpatialBundle::default(), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + radius, + ), + RigidBody::KinematicPositionBased, + // CollisionGroups::new(self_group, interaction_group), + // SolverGroups::new(self_group, interaction_group), + PhysicsHandBone::ThumbMetacarpal, + BoneInitState::False, + )); +} + +fn update_physics_hands( + HandRes: Option>, + mut bone_query: Query<( + &mut Transform, + &mut Collider, + &PhysicsHandBone, + &mut BoneInitState, + )>, + hand_query: Query<(&Transform, &HandBone, &Hand, Without)>, +) { + //sanity check do we even have hands? + match HandRes { + Some(res) => { + let radius = 0.010; + //lets just do the Right ThumbMetacarpal for now + let right_thumb_meta_entity = res.right.thumb.metacarpal; + let right_thumb_prox_entity = res.right.thumb.proximal; + + //now we need their transforms + let rtm = hand_query.get(right_thumb_meta_entity); + let rtp = hand_query.get(right_thumb_prox_entity); + let end = rtp.unwrap().0.translation - rtm.unwrap().0.translation; + if(end.length() < 0.001){ //i hate this but we need to skip init if the length is zero + return; + } + info!("end: {}", end.length()); + for mut bone in bone_query.iter_mut() { + match *bone.3 { + BoneInitState::True => { + //if we are init then we just move em? + *bone.0 = rtm.unwrap().0.clone().looking_at(rtp.unwrap().0.translation, Vec3::Y); + + }, + BoneInitState::False => { + if (*bone.2 == PhysicsHandBone::ThumbMetacarpal) { + //build a new collider? + *bone.1 = Collider::capsule( + Vec3::splat(0.0), + Vec3 { x: 0.0, y: 0.0, z: -end.length() }, + radius, + ); + *bone.3 = BoneInitState::True; + } + } + } + } + } + None => info!("hand states resource not initialized yet"), + } +} + #[derive(Event, Default)] pub struct SpawnCubeRequest; From 671a94765701570702db6ebba23492e18c4c683f Mon Sep 17 00:00:00 2001 From: Jay Christy Date: Wed, 25 Oct 2023 16:54:17 -0400 Subject: [PATCH 3/4] added the other metacarpals --- examples/demo/src/main.rs | 238 +++++++++++++++++++++++++++++++++----- src/xr_input/hand.rs | 12 +- 2 files changed, 219 insertions(+), 31 deletions(-) diff --git a/examples/demo/src/main.rs b/examples/demo/src/main.rs index d31adac..7456d4b 100644 --- a/examples/demo/src/main.rs +++ b/examples/demo/src/main.rs @@ -176,7 +176,7 @@ fn spawn_capsule( )); } -#[derive(Component, PartialEq)] +#[derive(Component, PartialEq, Debug)] pub enum PhysicsHandBone { Palm, Wrist, @@ -238,52 +238,162 @@ fn spawn_physics_hands(mut commands: Commands) { // SolverGroups::new(self_group, interaction_group), PhysicsHandBone::ThumbMetacarpal, BoneInitState::False, + Hand::Right, + )); + //index + //spawn the thing + commands.spawn(( + SpatialBundle::default(), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + radius, + ), + RigidBody::KinematicPositionBased, + // CollisionGroups::new(self_group, interaction_group), + // SolverGroups::new(self_group, interaction_group), + PhysicsHandBone::IndexMetacarpal, + BoneInitState::False, + Hand::Right, + )); + //middle + //spawn the thing + commands.spawn(( + SpatialBundle::default(), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + radius, + ), + RigidBody::KinematicPositionBased, + // CollisionGroups::new(self_group, interaction_group), + // SolverGroups::new(self_group, interaction_group), + PhysicsHandBone::MiddleMetacarpal, + BoneInitState::False, + Hand::Right, + )); + //ring + //spawn the thing + commands.spawn(( + SpatialBundle::default(), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + radius, + ), + RigidBody::KinematicPositionBased, + // CollisionGroups::new(self_group, interaction_group), + // SolverGroups::new(self_group, interaction_group), + PhysicsHandBone::RingMetacarpal, + BoneInitState::False, + Hand::Right, + )); + //little + //spawn the thing + commands.spawn(( + SpatialBundle::default(), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + radius, + ), + RigidBody::KinematicPositionBased, + // CollisionGroups::new(self_group, interaction_group), + // SolverGroups::new(self_group, interaction_group), + PhysicsHandBone::LittleMetacarpal, + BoneInitState::False, + Hand::Right, )); } fn update_physics_hands( - HandRes: Option>, + hands_res: Option>, mut bone_query: Query<( &mut Transform, &mut Collider, &PhysicsHandBone, &mut BoneInitState, + &Hand, )>, hand_query: Query<(&Transform, &HandBone, &Hand, Without)>, ) { //sanity check do we even have hands? - match HandRes { + match hands_res { Some(res) => { + //config stuff let radius = 0.010; - //lets just do the Right ThumbMetacarpal for now - let right_thumb_meta_entity = res.right.thumb.metacarpal; - let right_thumb_prox_entity = res.right.thumb.proximal; - - //now we need their transforms - let rtm = hand_query.get(right_thumb_meta_entity); - let rtp = hand_query.get(right_thumb_prox_entity); - let end = rtp.unwrap().0.translation - rtm.unwrap().0.translation; - if(end.length() < 0.001){ //i hate this but we need to skip init if the length is zero - return; - } - info!("end: {}", end.length()); for mut bone in bone_query.iter_mut() { + let hand_res = match bone.4 { + Hand::Left => res.left, + Hand::Right => res.right, + }; + + //lets just do the Right ThumbMetacarpal for now + let (start_entity, end_entity) = get_start_and_end_entities(hand_res, bone.2); + + //now we need their transforms + let start_components = hand_query.get(start_entity); + let end_components = hand_query.get(end_entity); + let direction = + end_components.unwrap().0.translation - start_components.unwrap().0.translation; + if direction.length() < 0.001 { + //i hate this but we need to skip init if the length is zero + return; + } + match *bone.3 { BoneInitState::True => { //if we are init then we just move em? - *bone.0 = rtm.unwrap().0.clone().looking_at(rtp.unwrap().0.translation, Vec3::Y); - - }, + *bone.0 = start_components + .unwrap() + .0 + .clone() + .looking_at(end_components.unwrap().0.translation, Vec3::Y); + } BoneInitState::False => { - if (*bone.2 == PhysicsHandBone::ThumbMetacarpal) { - //build a new collider? - *bone.1 = Collider::capsule( - Vec3::splat(0.0), - Vec3 { x: 0.0, y: 0.0, z: -end.length() }, - radius, - ); - *bone.3 = BoneInitState::True; - } + //build a new collider? + *bone.1 = Collider::capsule( + Vec3::splat(0.0), + Vec3 { + x: 0.0, + y: 0.0, + z: -direction.length(), + }, + radius, + ); + *bone.3 = BoneInitState::True; } } } @@ -292,6 +402,80 @@ fn update_physics_hands( } } +fn get_start_and_end_entities(hand_res: HandResource, bone: &PhysicsHandBone) -> (Entity, Entity) { + match bone { + PhysicsHandBone::Palm => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::Wrist => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::ThumbMetacarpal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::ThumbProximal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::ThumbDistal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::ThumbTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::IndexMetacarpal => { + return (hand_res.index.metacarpal, hand_res.index.proximal) + } + PhysicsHandBone::IndexProximal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::IndexIntermediate => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::IndexDistal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::IndexTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::MiddleMetacarpal => { + return (hand_res.middle.metacarpal, hand_res.middle.proximal) + } + PhysicsHandBone::MiddleProximal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::MiddleIntermediate => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::MiddleDistal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::MiddleTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::RingMetacarpal => { + return (hand_res.ring.metacarpal, hand_res.ring.proximal) + } + PhysicsHandBone::RingProximal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::RingIntermediate => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::RingDistal => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::RingTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::LittleMetacarpal => { + return (hand_res.little.metacarpal, hand_res.little.proximal) + } + PhysicsHandBone::LittleProximal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::LittleIntermediate => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::LittleDistal => { + return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + } + PhysicsHandBone::LittleTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + }; +} + +fn get_hand_res(res: &Res<'_, HandsResource>, hand: Hand) -> HandResource { + match hand { + Hand::Left => res.left.clone(), + Hand::Right => res.right.clone(), + } +} + #[derive(Event, Default)] pub struct SpawnCubeRequest; diff --git a/src/xr_input/hand.rs b/src/xr_input/hand.rs index 81f5936..f23b18f 100644 --- a/src/xr_input/hand.rs +++ b/src/xr_input/hand.rs @@ -38,7 +38,7 @@ impl Plugin for OpenXrHandInput { #[derive(Default)] pub struct HandInputDebugRenderer; -impl Plugin for HandInputDebugRenderer{ +impl Plugin for HandInputDebugRenderer { fn build(&self, app: &mut bevy::prelude::App) { app.add_systems(PostUpdate, draw_hand_entities); } @@ -56,12 +56,12 @@ impl Default for HandInputSource { } } -#[derive(Resource, Default)] +#[derive(Resource, Default, Clone, Copy)] pub struct HandsResource { pub left: HandResource, pub right: HandResource, } - +#[derive(Clone, Copy)] pub struct HandResource { pub palm: Entity, pub wrist: Entity, @@ -85,7 +85,7 @@ impl Default for HandResource { } } } - +#[derive(Clone, Copy)] pub struct ThumbResource { pub metacarpal: Entity, pub proximal: Entity, @@ -103,6 +103,7 @@ impl Default for ThumbResource { } } } +#[derive(Clone, Copy)] pub struct IndexResource { pub metacarpal: Entity, pub proximal: Entity, @@ -122,6 +123,7 @@ impl Default for IndexResource { } } } +#[derive(Clone, Copy)] pub struct MiddleResource { pub metacarpal: Entity, pub proximal: Entity, @@ -140,6 +142,7 @@ impl Default for MiddleResource { } } } +#[derive(Clone, Copy)] pub struct RingResource { pub metacarpal: Entity, pub proximal: Entity, @@ -158,6 +161,7 @@ impl Default for RingResource { } } } +#[derive(Clone, Copy)] pub struct LittleResource { pub metacarpal: Entity, pub proximal: Entity, From ec9b3ac01442a4d58c69ee1e83140ec20f5c3e2e Mon Sep 17 00:00:00 2001 From: Jay Christy Date: Wed, 25 Oct 2023 20:57:44 -0400 Subject: [PATCH 4/4] full hand bones --- examples/demo/src/main.rs | 305 +++++++++++++++----------------------- 1 file changed, 122 insertions(+), 183 deletions(-) diff --git a/examples/demo/src/main.rs b/examples/demo/src/main.rs index 7456d4b..0735820 100644 --- a/examples/demo/src/main.rs +++ b/examples/demo/src/main.rs @@ -176,7 +176,7 @@ fn spawn_capsule( )); } -#[derive(Component, PartialEq, Debug)] +#[derive(Component, PartialEq, Debug, Clone, Copy)] pub enum PhysicsHandBone { Palm, Wrist, @@ -212,130 +212,69 @@ pub enum BoneInitState { } fn spawn_physics_hands(mut commands: Commands) { + //here we go + let hands = [Hand::Left, Hand::Right]; + let bones = [ + PhysicsHandBone::Palm, + PhysicsHandBone::Wrist, + PhysicsHandBone::ThumbMetacarpal, + PhysicsHandBone::ThumbProximal, + PhysicsHandBone::ThumbDistal, + PhysicsHandBone::ThumbTip, + PhysicsHandBone::IndexMetacarpal, + PhysicsHandBone::IndexProximal, + PhysicsHandBone::IndexIntermediate, + PhysicsHandBone::IndexDistal, + PhysicsHandBone::IndexTip, + PhysicsHandBone::MiddleMetacarpal, + PhysicsHandBone::MiddleProximal, + PhysicsHandBone::MiddleIntermediate, + PhysicsHandBone::MiddleDistal, + PhysicsHandBone::MiddleTip, + PhysicsHandBone::RingMetacarpal, + PhysicsHandBone::RingProximal, + PhysicsHandBone::RingIntermediate, + PhysicsHandBone::RingDistal, + PhysicsHandBone::RingTip, + PhysicsHandBone::LittleMetacarpal, + PhysicsHandBone::LittleProximal, + PhysicsHandBone::LittleIntermediate, + PhysicsHandBone::LittleDistal, + PhysicsHandBone::LittleTip, + ]; //lets just do the Right ThumbMetacarpal for now //i dont understand the groups yet let self_group = Group::GROUP_1; let interaction_group = Group::ALL; let radius = 0.010; - //spawn the thing - commands.spawn(( - SpatialBundle::default(), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - radius, - ), - RigidBody::KinematicPositionBased, - // CollisionGroups::new(self_group, interaction_group), - // SolverGroups::new(self_group, interaction_group), - PhysicsHandBone::ThumbMetacarpal, - BoneInitState::False, - Hand::Right, - )); - //index - //spawn the thing - commands.spawn(( - SpatialBundle::default(), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - radius, - ), - RigidBody::KinematicPositionBased, - // CollisionGroups::new(self_group, interaction_group), - // SolverGroups::new(self_group, interaction_group), - PhysicsHandBone::IndexMetacarpal, - BoneInitState::False, - Hand::Right, - )); - //middle - //spawn the thing - commands.spawn(( - SpatialBundle::default(), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - radius, - ), - RigidBody::KinematicPositionBased, - // CollisionGroups::new(self_group, interaction_group), - // SolverGroups::new(self_group, interaction_group), - PhysicsHandBone::MiddleMetacarpal, - BoneInitState::False, - Hand::Right, - )); - //ring - //spawn the thing - commands.spawn(( - SpatialBundle::default(), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - radius, - ), - RigidBody::KinematicPositionBased, - // CollisionGroups::new(self_group, interaction_group), - // SolverGroups::new(self_group, interaction_group), - PhysicsHandBone::RingMetacarpal, - BoneInitState::False, - Hand::Right, - )); - //little - //spawn the thing - commands.spawn(( - SpatialBundle::default(), - Collider::capsule( - Vec3 { - x: 0.0, - y: -0.0575, - z: 0.0, - }, - Vec3 { - x: 0.0, - y: 0.0575, - z: 0.0, - }, - radius, - ), - RigidBody::KinematicPositionBased, - // CollisionGroups::new(self_group, interaction_group), - // SolverGroups::new(self_group, interaction_group), - PhysicsHandBone::LittleMetacarpal, - BoneInitState::False, - Hand::Right, - )); + + for hand in hands.iter() { + for bone in bones.iter() { + //spawn the thing + commands.spawn(( + SpatialBundle::default(), + Collider::capsule( + Vec3 { + x: 0.0, + y: -0.0575, + z: 0.0, + }, + Vec3 { + x: 0.0, + y: 0.0575, + z: 0.0, + }, + radius, + ), + RigidBody::KinematicPositionBased, + // CollisionGroups::new(self_group, interaction_group), + // SolverGroups::new(self_group, interaction_group), + bone.clone(), + BoneInitState::False, + hand.clone(), + )); + } + } } fn update_physics_hands( @@ -361,39 +300,40 @@ fn update_physics_hands( }; //lets just do the Right ThumbMetacarpal for now - let (start_entity, end_entity) = get_start_and_end_entities(hand_res, bone.2); - - //now we need their transforms - let start_components = hand_query.get(start_entity); - let end_components = hand_query.get(end_entity); - let direction = - end_components.unwrap().0.translation - start_components.unwrap().0.translation; - if direction.length() < 0.001 { - //i hate this but we need to skip init if the length is zero - return; - } - - match *bone.3 { - BoneInitState::True => { - //if we are init then we just move em? - *bone.0 = start_components - .unwrap() - .0 - .clone() - .looking_at(end_components.unwrap().0.translation, Vec3::Y); + let result = get_start_and_end_entities(hand_res, bone.2); + if let Some((start_entity, end_entity)) = result { + //now we need their transforms + let start_components = hand_query.get(start_entity); + let end_components = hand_query.get(end_entity); + let direction = end_components.unwrap().0.translation + - start_components.unwrap().0.translation; + if direction.length() < 0.001 { + //i hate this but we need to skip init if the length is zero + return; } - BoneInitState::False => { - //build a new collider? - *bone.1 = Collider::capsule( - Vec3::splat(0.0), - Vec3 { - x: 0.0, - y: 0.0, - z: -direction.length(), - }, - radius, - ); - *bone.3 = BoneInitState::True; + + match *bone.3 { + BoneInitState::True => { + //if we are init then we just move em? + *bone.0 = start_components + .unwrap() + .0 + .clone() + .looking_at(end_components.unwrap().0.translation, Vec3::Y); + } + BoneInitState::False => { + //build a new collider? + *bone.1 = Collider::capsule( + Vec3::splat(0.0), + Vec3 { + x: 0.0, + y: 0.0, + z: -direction.length(), + }, + radius, + ); + *bone.3 = BoneInitState::True; + } } } } @@ -402,70 +342,69 @@ fn update_physics_hands( } } -fn get_start_and_end_entities(hand_res: HandResource, bone: &PhysicsHandBone) -> (Entity, Entity) { +fn get_start_and_end_entities( + hand_res: HandResource, + bone: &PhysicsHandBone, +) -> Option<(Entity, Entity)> { match bone { - PhysicsHandBone::Palm => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), - PhysicsHandBone::Wrist => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::Palm => return None, + PhysicsHandBone::Wrist => return None, PhysicsHandBone::ThumbMetacarpal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.thumb.metacarpal, hand_res.thumb.proximal)) } PhysicsHandBone::ThumbProximal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.thumb.proximal, hand_res.thumb.distal)) } - PhysicsHandBone::ThumbDistal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) - } - PhysicsHandBone::ThumbTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::ThumbDistal => return Some((hand_res.thumb.distal, hand_res.thumb.tip)), + PhysicsHandBone::ThumbTip => return None, PhysicsHandBone::IndexMetacarpal => { - return (hand_res.index.metacarpal, hand_res.index.proximal) + return Some((hand_res.index.metacarpal, hand_res.index.proximal)) } PhysicsHandBone::IndexProximal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.index.proximal, hand_res.index.intermediate)) } PhysicsHandBone::IndexIntermediate => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.index.intermediate, hand_res.index.distal)) } - PhysicsHandBone::IndexDistal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) - } - PhysicsHandBone::IndexTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::IndexDistal => return Some((hand_res.index.distal, hand_res.index.tip)), + PhysicsHandBone::IndexTip => return None, PhysicsHandBone::MiddleMetacarpal => { - return (hand_res.middle.metacarpal, hand_res.middle.proximal) + return Some((hand_res.middle.metacarpal, hand_res.middle.proximal)) } PhysicsHandBone::MiddleProximal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.middle.proximal, hand_res.middle.intermediate)) } PhysicsHandBone::MiddleIntermediate => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.middle.intermediate, hand_res.middle.distal)) } PhysicsHandBone::MiddleDistal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.middle.distal, hand_res.middle.tip)) } - PhysicsHandBone::MiddleTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::MiddleTip => return None, PhysicsHandBone::RingMetacarpal => { - return (hand_res.ring.metacarpal, hand_res.ring.proximal) + return Some((hand_res.ring.metacarpal, hand_res.ring.proximal)) } PhysicsHandBone::RingProximal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.ring.proximal, hand_res.ring.intermediate)) } PhysicsHandBone::RingIntermediate => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.ring.intermediate, hand_res.ring.distal)) } - PhysicsHandBone::RingDistal => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), - PhysicsHandBone::RingTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::RingDistal => return Some((hand_res.ring.distal, hand_res.ring.tip)), + PhysicsHandBone::RingTip => return None, PhysicsHandBone::LittleMetacarpal => { - return (hand_res.little.metacarpal, hand_res.little.proximal) + return Some((hand_res.little.metacarpal, hand_res.little.proximal)) } PhysicsHandBone::LittleProximal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.little.proximal, hand_res.little.intermediate)) } PhysicsHandBone::LittleIntermediate => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.little.intermediate, hand_res.little.distal)) } PhysicsHandBone::LittleDistal => { - return (hand_res.thumb.metacarpal, hand_res.thumb.proximal) + return Some((hand_res.little.distal, hand_res.little.tip)) } - PhysicsHandBone::LittleTip => return (hand_res.thumb.metacarpal, hand_res.thumb.proximal), + PhysicsHandBone::LittleTip => return None, }; }