This commit is contained in:
Schmarni
2023-11-16 06:09:36 +01:00
parent 851c7b7587
commit 5b443c3b35
6 changed files with 189 additions and 194 deletions

View File

@@ -29,7 +29,7 @@ use bevy_oxr::{
oculus_touch::OculusController, oculus_touch::OculusController,
prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig}, prototype_locomotion::{proto_locomotion, PrototypeLocomotionConfig},
trackers::{OpenXRController, OpenXRLeftController, OpenXRRightController, OpenXRTracker}, trackers::{OpenXRController, OpenXRLeftController, OpenXRRightController, OpenXRTracker},
Hand, Hand, actions::XrActionSets,
}, },
DefaultXrPlugins, DefaultXrPlugins,
}; };

View File

@@ -23,12 +23,10 @@ use openxr as xr;
use resources::*; use resources::*;
use xr_input::controllers::XrControllerType; use xr_input::controllers::XrControllerType;
use xr_input::hands::emulated::EmulatedHandsPlugin; use xr_input::hands::emulated::EmulatedHandsPlugin;
use xr_input::hands::hand_tracking::HandTrackingPlugin; use xr_input::hands::hand_tracking::{HandTrackingPlugin, HandTrackingData};
use xr_input::handtracking::HandTrackingTracker; use xr_input::handtracking::HandTrackingTracker;
use xr_input::OpenXrInput; use xr_input::OpenXrInput;
use crate::xr_input::oculus_touch::ActionSets;
const VIEW_TYPE: xr::ViewConfigurationType = xr::ViewConfigurationType::PRIMARY_STEREO; const VIEW_TYPE: xr::ViewConfigurationType = xr::ViewConfigurationType::PRIMARY_STEREO;
pub const LEFT_XR_TEXTURE_HANDLE: ManualTextureViewHandle = ManualTextureViewHandle(1208214591); pub const LEFT_XR_TEXTURE_HANDLE: ManualTextureViewHandle = ManualTextureViewHandle(1208214591);
@@ -91,7 +89,7 @@ impl Plugin for OpenXrPlugin {
views, views,
frame_state, frame_state,
hand_tracking_enabled, hand_tracking_enabled,
) = graphics::initialize_xr_graphics(primary_window,self.0).unwrap(); ) = graphics::initialize_xr_graphics(primary_window, self.0).unwrap();
// std::thread::sleep(Duration::from_secs(5)); // std::thread::sleep(Duration::from_secs(5));
debug!("Configured wgpu adapter Limits: {:#?}", device.limits()); debug!("Configured wgpu adapter Limits: {:#?}", device.limits());
debug!("Configured wgpu adapter Features: {:#?}", device.features()); debug!("Configured wgpu adapter Features: {:#?}", device.features());
@@ -163,10 +161,9 @@ impl Plugin for OpenXrPlugin {
.insert_resource(action_sets.clone()); .insert_resource(action_sets.clone());
let hands = xr_instance.exts().ext_hand_tracking.is_some(); let hands = xr_instance.exts().ext_hand_tracking.is_some();
if hands { if hands {
app.insert_resource(HandTrackingTracker::new(&session).unwrap()); app.insert_resource(HandTrackingData::new(&session).unwrap());
app.insert_resource(HandInputSource::OpenXr);
} else { } else {
app.insert_resource(HandInputSource::Emulated); app.insert_resource(DisableHandTracking::Both);
} }
let (left, right) = swapchain.get_render_views(); let (left, right) = swapchain.get_render_views();
@@ -224,7 +221,8 @@ impl PluginGroup for DefaultXrPlugins {
.disable::<PipelinedRenderingPlugin>() .disable::<PipelinedRenderingPlugin>()
.add_before::<RenderPlugin, _>(OpenXrPlugin::default()) .add_before::<RenderPlugin, _>(OpenXrPlugin::default())
.add_after::<OpenXrPlugin, _>(OpenXrInput::new(XrControllerType::OculusTouch)) .add_after::<OpenXrPlugin, _>(OpenXrInput::new(XrControllerType::OculusTouch))
.add(EmulatedHandsPlugin).add(HandTrackingPlugin) .add(EmulatedHandsPlugin)
.add(HandTrackingPlugin)
.set(WindowPlugin { .set(WindowPlugin {
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
primary_window: Some(Window { primary_window: Some(Window {

View File

@@ -17,7 +17,7 @@ use super::{
actions::XrActionSets, actions::XrActionSets,
handtracking::{HandTrackingRef, HandTrackingTracker}, handtracking::{HandTrackingRef, HandTrackingTracker},
trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTrackingRoot}, trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTrackingRoot},
QuatConv, QuatConv, hands::hand_tracking::HandTrackingData,
}; };
/// add debug renderer for controllers /// add debug renderer for controllers
@@ -55,19 +55,16 @@ pub fn draw_gizmos(
Without<OpenXRLeftController>, Without<OpenXRLeftController>,
Without<OpenXRTrackingRoot>, Without<OpenXRTrackingRoot>,
)>, )>,
hand_tracking: Option<Res<HandTrackingTracker>>, hand_tracking: Option<Res<HandTrackingData>>,
action_sets: Res<XrActionSets>, action_sets: Res<XrActionSets>,
) { ) {
if let Some(hand_tracking) = hand_tracking { if let Some(hand_tracking) = hand_tracking {
let handtracking_ref = hand_tracking.get_ref(&xr_input, &frame_state); let handtracking_ref = hand_tracking.get_ref(&xr_input, &frame_state);
if let Some(joints) = handtracking_ref.get_left_poses() { if let Some(joints) = handtracking_ref.get_poses(Hand::Left) {
for joint in joints { for joint in joints.inner() {
let p = joint.pose.position; let trans = Transform::from_rotation(joint.orientation);
let r = joint.pose.orientation;
let quat = r.to_quat();
let trans = Transform::from_rotation(quat);
gizmos.circle( gizmos.circle(
(p.x, p.y, p.z).into(), joint.position,
trans.forward(), trans.forward(),
joint.radius, joint.radius,
Color::ORANGE_RED, Color::ORANGE_RED,
@@ -76,14 +73,11 @@ pub fn draw_gizmos(
} else { } else {
info!("left_hand_poses returned None"); info!("left_hand_poses returned None");
} }
if let Some(joints) = handtracking_ref.get_right_poses() { if let Some(joints) = handtracking_ref.get_poses(Hand::Right) {
for joint in joints { for joint in joints.inner() {
let p = joint.pose.position; let trans = Transform::from_rotation(joint.orientation);
let r = joint.pose.orientation;
let quat = r.to_quat();
let trans = Transform::from_rotation(quat);
gizmos.circle( gizmos.circle(
(p.x, p.y, p.z).into(), joint.position,
trans.forward(), trans.forward(),
joint.radius, joint.radius,
Color::LIME_GREEN, Color::LIME_GREEN,

View File

@@ -16,10 +16,11 @@ use crate::{
use super::{ use super::{
actions::XrActionSets, actions::XrActionSets,
hand_poses::get_simulated_open_hand_transforms, hand_poses::get_simulated_open_hand_transforms,
hands::{BoneTrackingStatus, HandBone},
handtracking::HandTrackingTracker, handtracking::HandTrackingTracker,
oculus_touch::OculusController, oculus_touch::OculusController,
trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTracker, OpenXRTrackingRoot}, trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTracker, OpenXRTrackingRoot},
Hand, QuatConv, hands::{HandBone, BoneTrackingStatus}, Hand, QuatConv,
}; };
/// add debug renderer for controllers /// add debug renderer for controllers
@@ -32,8 +33,8 @@ impl Plugin for OpenXrHandInput {
// .add_systems(Update, update_hand_skeletons) // .add_systems(Update, update_hand_skeletons)
// .add_systems(PreUpdate, update_hand_states) // .add_systems(PreUpdate, update_hand_states)
.add_systems(Startup, spawn_hand_entities); .add_systems(Startup, spawn_hand_entities);
// .insert_resource(HandStatesResource::default()) // .insert_resource(HandStatesResource::default())
// .insert_resource(HandInputSource::default()); // .insert_resource(HandInputSource::default());
} }
} }
@@ -198,6 +199,7 @@ pub fn spawn_hand_entities(mut commands: Commands) {
OpenXRTracker, OpenXRTracker,
hand.clone(), hand.clone(),
BoneTrackingStatus::Emulated, BoneTrackingStatus::Emulated,
HandBoneRadius(1.0),
)) ))
.id(); .id();
match hand { match hand {
@@ -267,7 +269,6 @@ pub fn spawn_hand_entities(mut commands: Commands) {
commands.insert_resource(hand_resource); commands.insert_resource(hand_resource);
} }
pub fn update_hand_states( pub fn update_hand_states(
oculus_controller: Res<OculusController>, oculus_controller: Res<OculusController>,
hand_states_option: Option<ResMut<HandStatesResource>>, hand_states_option: Option<ResMut<HandStatesResource>>,
@@ -1063,20 +1064,20 @@ pub struct HandBoneRadius(pub f32);
pub fn draw_hand_entities( pub fn draw_hand_entities(
mut gizmos: Gizmos, mut gizmos: Gizmos,
query: Query<(&Transform, &HandBone, Option<&HandBoneRadius>)>, query: Query<(&Transform, &HandBone, &HandBoneRadius)>,
) { ) {
for (transform, hand_bone, hand_bone_radius) in query.iter() { for (transform, hand_bone, hand_bone_radius) in query.iter() {
let (radius, color) = get_bone_gizmo_style(hand_bone); let (_, color) = get_bone_gizmo_style(hand_bone);
gizmos.sphere( gizmos.sphere(
transform.translation, transform.translation,
transform.rotation, transform.rotation,
hand_bone_radius.map_or(radius, |r| r.0), hand_bone_radius.0,
color, color,
); );
} }
} }
fn get_bone_gizmo_style(hand_bone: &HandBone) -> (f32, Color) { pub(crate) fn get_bone_gizmo_style(hand_bone: &HandBone) -> (f32, Color) {
match hand_bone { match hand_bone {
HandBone::Palm => (0.01, Color::WHITE), HandBone::Palm => (0.01, Color::WHITE),
HandBone::Wrist => (0.01, Color::GRAY), HandBone::Wrist => (0.01, Color::GRAY),

View File

@@ -6,15 +6,19 @@ use openxr::{Action, ActionTy, Binding, HandJoint};
use crate::{ use crate::{
resources::{XrInstance, XrSession}, resources::{XrInstance, XrSession},
xr_input::{ xr_input::{
actions::{
ActionHandednes, ActionType, SetupActionSet, SetupActionSets, XrActionSets, XrBinding,
},
controllers::Touchable, controllers::Touchable,
hand::{get_bone_gizmo_style, HandBoneRadius},
hand_poses::get_simulated_open_hand_transforms, hand_poses::get_simulated_open_hand_transforms,
oculus_touch::ActionSets, oculus_touch::ActionSets,
trackers::{OpenXRLeftController, OpenXRRightController}, trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTrackingRoot},
Hand, InteractionProfileBindings, Hand, InteractionProfileBindings,
}, },
}; };
use super::HandBone; use super::{BoneTrackingStatus, HandBone};
pub enum TouchValue<T: ActionTy> { pub enum TouchValue<T: ActionTy> {
None, None,
@@ -32,152 +36,119 @@ pub struct EmulatedHandsPlugin;
impl Plugin for EmulatedHandsPlugin { impl Plugin for EmulatedHandsPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, update_hand_skeleton_from_emulated); app.add_systems(PreUpdate, update_hand_skeleton_from_emulated);
app.add_systems( app.add_systems(Startup, setup_hand_emulation_action_set);
Startup,
setup_hand_emulation_action_set.map(|res| res.unwrap()),
);
} }
} }
#[derive(Resource)]
pub struct HandEmulationActionSet {
thumb_touch: Action<bool>,
thumb_x: Action<f32>,
thumb_y: Action<f32>,
index: Touchable<f32>,
middle: Touchable<f32>,
ring: Touchable<f32>,
little: Touchable<f32>,
}
fn setup_hand_emulation_action_set( const HAND_ACTION_SET: &'static str = "hand_pose_approx";
instance: Res<XrInstance>,
session: Res<XrSession>,
mut action_sets: ResMut<ActionSets>,
mut commands: Commands,
mut bindings: ResMut<InteractionProfileBindings>
) -> anyhow::Result<()> {
let left_path = instance.string_to_path("/user/hand/left").unwrap();
let right_path = instance.string_to_path("/user/hand/right").unwrap();
let hands = [left_path, right_path];
// This unwrap Should not trigger since both strings are not empty
let action_set = instance
.create_action_set("hand_pose_approximation_set", "Hand Pose Approximaiton", 0)
.unwrap();
let hand_action_set = HandEmulationActionSet {
thumb_touch: action_set.create_action::<bool>("thumb_touch", "Thumb Touched", &hands)?,
thumb_x: action_set.create_action::<f32>("thumb_x", "Thumb X", &hands)?,
thumb_y: action_set.create_action::<f32>("thumb_y", "Thumb Y", &hands)?,
index: Touchable::<f32> { fn setup_hand_emulation_action_set(mut action_sets: ResMut<SetupActionSets>) {
inner: action_set.create_action("index_value", "Index Finger Pull", &hands)?, let mut action_set = action_sets.add_action_set(HAND_ACTION_SET, "Hand Pose Approximaiton", 0);
touch: action_set.create_action("index_touch", "Index Finger Touch", &hands)?, action_set.new_action(
}, "thumb_touch",
middle: Touchable::<f32> { "Thumb Touched",
inner: action_set.create_action("middle_value", "Middle Finger Pull", &hands)?, ActionType::Bool,
touch: action_set.create_action("middle_touch", "Middle Finger Touch", &hands)?, ActionHandednes::Double,
}, );
ring: Touchable::<f32> { action_set.new_action(
inner: action_set.create_action("ring_value", "Ring Finger Pull", &hands)?, "thumb_x",
touch: action_set.create_action("ring_touch", "Ring Finger Touch", &hands)?, "Thumb X",
}, ActionType::F32,
little: Touchable::<f32> { ActionHandednes::Double,
inner: action_set.create_action("little_value", "Little Finger Pull", &hands)?, );
touch: action_set.create_action("little_touch", "Little Finger Touch", &hands)?, action_set.new_action(
}, "thumb_y",
}; "Thumb Y",
ActionType::F32,
ActionHandednes::Double,
);
suggest_oculus_touch_profile(&instance, &hand_action_set,bindings)?; action_set.new_action(
"index_touch",
"Index Finger Touched",
ActionType::Bool,
ActionHandednes::Double,
);
action_set.new_action(
"index_value",
"Index Finger Pull",
ActionType::F32,
ActionHandednes::Double,
);
session.attach_action_sets(&[&action_set])?; action_set.new_action(
"middle_value",
"Middle Finger Pull",
ActionType::F32,
ActionHandednes::Double,
);
action_set.new_action(
"ring_value",
"Ring Finger Pull",
ActionType::F32,
ActionHandednes::Double,
);
action_set.new_action(
"little_value",
"Little Finger Pull",
ActionType::F32,
ActionHandednes::Double,
);
action_sets.0.push(action_set); suggest_oculus_touch_profile(&mut action_set);
commands.insert_resource(hand_action_set);
Ok(())
} }
pub struct EmulatedHandPoseData {} pub struct EmulatedHandPoseData {}
fn bind<'a, T: ActionTy>( fn suggest_oculus_touch_profile(action_set: &mut SetupActionSet) {
action: &'a Action<T>, action_set.suggest_binding(
path: &str, "/interaction_profiles/oculus/touch_controller",
i: &XrInstance, &[
bindings: &mut Vec<Binding<'a>>, XrBinding::new("thumb_x", "/user/hand/left/input/thumbstick/x"),
) -> anyhow::Result<()> { XrBinding::new("thumb_x", "/user/hand/right/input/thumbstick/x"),
bindings.push(Binding::new( XrBinding::new("thumb_y", "/user/hand/left/input/thumbstick/y"),
&action, XrBinding::new("thumb_y", "/user/hand/right/input/thumbstick/y"),
i.string_to_path(&("/user/hand/left/input".to_string() + path))?, XrBinding::new("thumb_touch", "/user/hand/left/input/thumbstick/touch"),
)); XrBinding::new("thumb_touch", "/user/hand/right/input/thumbstick/touch"),
bindings.push(Binding::new( XrBinding::new("thumb_touch", "/user/hand/left/input/x/touch"),
&action, XrBinding::new("thumb_touch", "/user/hand/left/input/y/touch"),
i.string_to_path(&("/user/hand/right/input".to_string() + path))?, XrBinding::new("thumb_touch", "/user/hand/right/input/a/touch"),
)); XrBinding::new("thumb_touch", "/user/hand/right/input/b/touch"),
Ok(()) XrBinding::new("thumb_touch", "/user/hand/left/input/thumbrest/touch"),
} XrBinding::new("thumb_touch", "/user/hand/right/input/thumbrest/touch"),
fn bind_single<'a, T: ActionTy>( XrBinding::new("index_touch", "/user/hand/left/input/trigger/touch"),
action: &'a Action<T>, XrBinding::new("index_value", "/user/hand/left/input/trigger/value"),
path: &str, XrBinding::new("index_touch", "/user/hand/right/input/trigger/touch"),
hand: Hand, XrBinding::new("index_value", "/user/hand/right/input/trigger/value"),
i: &XrInstance, XrBinding::new("middle_value", "/user/hand/left/input/squeeze/value"),
bindings: &mut Vec<Binding<'a>>, XrBinding::new("middle_value", "/user/hand/right/input/squeeze/value"),
) -> anyhow::Result<()> { XrBinding::new("ring_value", "/user/hand/left/input/squeeze/value"),
match hand { XrBinding::new("ring_value", "/user/hand/right/input/squeeze/value"),
Hand::Left => bindings.push(Binding::new( XrBinding::new("little_value", "/user/hand/left/input/squeeze/value"),
&action, XrBinding::new("little_value", "/user/hand/right/input/squeeze/value"),
i.string_to_path(&("/user/hand/left/input".to_string() + path))?, ],
)), );
Hand::Right => bindings.push(Binding::new(
&action,
i.string_to_path(&("/user/hand/right/input".to_string() + path))?,
)),
}
Ok(())
}
fn suggest_oculus_touch_profile(
i: &XrInstance,
action_set: &HandEmulationActionSet,
mut bindings: ResMut<InteractionProfileBindings>
) -> anyhow::Result<()> {
let mut b = bindings.entry("/interaction_profiles/oculus/touch_controller").or_default();
bind(&action_set.thumb_x, "/thumbstick/x", i, &mut b)?;
bind(&action_set.thumb_y, "/thumbstick/y", i, &mut b)?;
bind(&action_set.thumb_touch, "/thumbstick/touch", i, &mut b)?;
bind(&action_set.thumb_touch, "/thumbrest/touch", i, &mut b)?;
// bind_single(&action_set.thumb_touch, "/x/touch", Hand::Left, i, &mut b)?;
// bind_single(&action_set.thumb_touch, "/y/touch", Hand::Left, i, &mut b)?;
// bind_single(&action_set.thumb_touch, "/a/touch", Hand::Right, i, &mut b)?;
// bind_single(&action_set.thumb_touch, "/b/touch", Hand::Right, i, &mut b)?;
// bind(&action_set.index.touch, "/trigger/touch", i, &mut b)?;
// bind(&action_set.index.inner, "/trigger/value", i, &mut b)?;
//
// bind(&action_set.middle.touch, "/squeeze/touch", i, &mut b)?;
// bind(&action_set.middle.inner, "/squeeze/value", i, &mut b)?;
// bind(&action_set.ring.touch, "/squeeze/touch", i, &mut b)?;
// bind(&action_set.ring.inner, "/squeeze/value", i, &mut b)?;
// bind(&action_set.little.touch, "/squeeze/touch", i, &mut b)?;
// bind(&action_set.little.inner, "/squeeze/value", i, &mut b)?;
i.suggest_interaction_profile_bindings(
i.string_to_path("/interaction_profiles/oculus/touch_controller")?,
&b,
)?;
Ok(())
} }
pub(crate) fn update_hand_skeleton_from_emulated( pub(crate) fn update_hand_skeleton_from_emulated(
session: Res<XrSession>, session: Res<XrSession>,
instance: Res<XrInstance>, instance: Res<XrInstance>,
action_set: Res<HandEmulationActionSet>, action_sets: Res<XrActionSets>,
left_controller_transform: Query<&Transform, With<OpenXRLeftController>>, left_controller_transform: Query<&Transform, With<OpenXRLeftController>>,
right_controller_transform: Query<&Transform, With<OpenXRRightController>>, right_controller_transform: Query<&Transform, With<OpenXRRightController>>,
tracking_root_transform: Query<&Transform, With<OpenXRTrackingRoot>>,
mut bones: Query< mut bones: Query<
(&mut Transform, &HandBone, &Hand), (
&mut Transform,
&HandBone,
&Hand,
&BoneTrackingStatus,
&mut HandBoneRadius,
),
( (
Without<OpenXRLeftController>, Without<OpenXRLeftController>,
Without<OpenXRRightController>, Without<OpenXRRightController>,
Without<OpenXRTrackingRoot>,
), ),
>, >,
) { ) {
@@ -192,8 +163,9 @@ pub(crate) fn update_hand_skeleton_from_emulated(
Hand::Right, Hand::Right,
), ),
] { ] {
let thumb_curl = match action_set let thumb_curl = match action_sets
.thumb_touch .get_action_bool(HAND_ACTION_SET, "thumb_touch")
.unwrap()
.state(&session, subaction_path) .state(&session, subaction_path)
.unwrap() .unwrap()
.current_state .current_state
@@ -201,27 +173,27 @@ pub(crate) fn update_hand_skeleton_from_emulated(
true => 1.0, true => 1.0,
false => 0.0, false => 0.0,
}; };
let index_curl = action_set let index_curl = action_sets
.index .get_action_f32(HAND_ACTION_SET, "index_value")
.inner .unwrap()
.state(&session, subaction_path) .state(&session, subaction_path)
.unwrap() .unwrap()
.current_state; .current_state;
let middle_curl = action_set let middle_curl = action_sets
.middle .get_action_f32(HAND_ACTION_SET, "middle_value")
.inner .unwrap()
.state(&session, subaction_path) .state(&session, subaction_path)
.unwrap() .unwrap()
.current_state; .current_state;
let ring_curl = action_set let ring_curl = action_sets
.ring .get_action_f32(HAND_ACTION_SET, "ring_value")
.inner .unwrap()
.state(&session, subaction_path) .state(&session, subaction_path)
.unwrap() .unwrap()
.current_state; .current_state;
let little_curl = action_set let little_curl = action_sets
.little .get_action_f32(HAND_ACTION_SET, "little_value")
.inner .unwrap()
.state(&session, subaction_path) .state(&session, subaction_path)
.unwrap() .unwrap()
.current_state; .current_state;
@@ -241,11 +213,21 @@ pub(crate) fn update_hand_skeleton_from_emulated(
little_curl, little_curl,
); );
} }
for (mut t, bone, hand) in bones.iter_mut() { let trt = tracking_root_transform.single();
for (mut t, bone, hand, status, mut radius) in bones.iter_mut() {
match status {
BoneTrackingStatus::Emulated => {}
BoneTrackingStatus::Tracked => continue,
}
radius.0 = get_bone_gizmo_style(bone).0;
*t = data[match hand { *t = data[match hand {
Hand::Left => 0, Hand::Left => 0,
Hand::Right => 1, Hand::Right => 1,
}][bone.get_index_from_bone()] }][bone.get_index_from_bone()];
*t = t.with_scale(trt.scale);
*t = t.with_rotation(trt.rotation * t.rotation);
*t = t.with_translation(trt.transform_point(t.translation));
} }
} }
pub fn update_hand_bones_emulated( pub fn update_hand_bones_emulated(
@@ -537,6 +519,15 @@ pub fn update_hand_bones_emulated(
calc_transforms calc_transforms
} }
fn get_bone_curl_angle(bone: HandJoint, thumb_curl: f32) -> f32 { fn get_bone_curl_angle(bone: HandJoint, curl: f32) -> f32 {
todo!() let mul: f32 = match bone {
HandJoint::INDEX_PROXIMAL => 0.0,
HandJoint::MIDDLE_PROXIMAL => 0.0,
HandJoint::RING_PROXIMAL => 0.0,
HandJoint::LITTLE_PROXIMAL => 0.0,
HandJoint::THUMB_PROXIMAL => 0.0,
_ => 1.0,
};
let curl_angle = -((mul * curl * 80.0) + 5.0);
return curl_angle;
} }

View File

@@ -55,18 +55,23 @@ pub struct HandTrackingRef<'a> {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct HandJoint { pub struct HandJoint {
position: Vec3, pub position: Vec3,
position_valid: bool, pub position_valid: bool,
position_tracked: bool, pub position_tracked: bool,
orientaion: Quat, pub orientation: Quat,
orientaion_valid: bool, pub orientation_valid: bool,
orientaion_tracked: bool, pub orientation_tracked: bool,
radius: f32, pub radius: f32,
} }
pub struct HandJoints { pub struct HandJoints {
inner: [HandJoint; 26], inner: [HandJoint; 26],
} }
impl HandJoints {
pub fn inner(&self) -> &[HandJoint; 26] {
&self.inner
}
}
impl HandJoints { impl HandJoints {
pub fn get_joint(&self, bone: HandBone) -> &HandJoint { pub fn get_joint(&self, bone: HandBone) -> &HandJoint {
@@ -91,17 +96,17 @@ impl<'a> HandTrackingRef<'a> {
.into_iter() .into_iter()
.map(|joint| HandJoint { .map(|joint| HandJoint {
position: joint.pose.position.to_vec3(), position: joint.pose.position.to_vec3(),
orientaion: joint.pose.orientation.to_quat(), orientation: joint.pose.orientation.to_quat(),
position_valid: joint position_valid: joint
.location_flags .location_flags
.contains(SpaceLocationFlags::POSITION_VALID), .contains(SpaceLocationFlags::POSITION_VALID),
position_tracked: joint position_tracked: joint
.location_flags .location_flags
.contains(SpaceLocationFlags::POSITION_TRACKED), .contains(SpaceLocationFlags::POSITION_TRACKED),
orientaion_valid: joint orientation_valid: joint
.location_flags .location_flags
.contains(SpaceLocationFlags::ORIENTATION_VALID), .contains(SpaceLocationFlags::ORIENTATION_VALID),
orientaion_tracked: joint orientation_tracked: joint
.location_flags .location_flags
.contains(SpaceLocationFlags::ORIENTATION_TRACKED), .contains(SpaceLocationFlags::ORIENTATION_TRACKED),
radius: joint.radius, radius: joint.radius,
@@ -126,8 +131,8 @@ impl Plugin for HandTrackingPlugin {
} }
pub fn update_hand_bones( pub fn update_hand_bones(
disabled_tracking: Res<DisableHandTracking>, disabled_tracking: Option<Res<DisableHandTracking>>,
hand_tracking: Res<HandTrackingData>, hand_tracking: Option<Res<HandTrackingData>>,
xr_input: Res<XrInput>, xr_input: Res<XrInput>,
xr_frame_state: Res<XrFrameState>, xr_frame_state: Res<XrFrameState>,
root_query: Query<(&Transform, With<OpenXRTrackingRoot>, Without<HandBone>)>, root_query: Query<(&Transform, With<OpenXRTrackingRoot>, Without<HandBone>)>,
@@ -139,19 +144,25 @@ pub fn update_hand_bones(
&mut BoneTrackingStatus, &mut BoneTrackingStatus,
)>, )>,
) { ) {
let hand_ref = hand_tracking.get_ref(&xr_input, &xr_frame_state); let hand_ref = match hand_tracking.as_ref() {
Some(h) => h.get_ref(&xr_input, &xr_frame_state),
None => {
warn!("No Handtracking data!");
return;
}
};
let (root_transform, _, _) = root_query.get_single().unwrap(); let (root_transform, _, _) = root_query.get_single().unwrap();
let left_hand_data = hand_ref.get_poses(Hand::Left); let left_hand_data = hand_ref.get_poses(Hand::Left);
let right_hand_data = hand_ref.get_poses(Hand::Right); let right_hand_data = hand_ref.get_poses(Hand::Right);
bones bones
.par_iter_mut() .par_iter_mut()
.for_each(|(mut transform, hand, bone, mut radius, mut status)| { .for_each(|(mut transform, hand, bone, mut radius, mut status)| {
match (&hand, disabled_tracking.as_ref()) { match (&hand, disabled_tracking.as_ref().map(|d| d.as_ref())) {
(Hand::Left, DisableHandTracking::OnlyLeft) => { (Hand::Left, Some(DisableHandTracking::OnlyLeft)) => {
*status = BoneTrackingStatus::Emulated; *status = BoneTrackingStatus::Emulated;
return; return;
} }
(Hand::Right, DisableHandTracking::OnlyRight) => { (Hand::Right, Some(DisableHandTracking::OnlyRight)) => {
*status = BoneTrackingStatus::Emulated; *status = BoneTrackingStatus::Emulated;
return; return;
} }
@@ -171,6 +182,6 @@ pub fn update_hand_bones(
radius.0 = bone_data.radius; radius.0 = bone_data.radius;
*transform = transform *transform = transform
.with_translation(root_transform.transform_point(bone_data.position)) .with_translation(root_transform.transform_point(bone_data.position))
.with_rotation(root_transform.rotation * bone_data.orientaion) .with_rotation(root_transform.rotation * bone_data.orientation)
}); });
} }