Done
This commit is contained in:
@@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
14
src/lib.rs
14
src/lib.rs
@@ -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 {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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),
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user