Small cleanup, and moved hand.rs to hands/common.rs

This commit is contained in:
Schmarni
2023-11-16 21:26:49 +01:00
parent fe15e89acd
commit 200be97846
13 changed files with 417 additions and 1126 deletions

View File

@@ -5,7 +5,6 @@ pub mod resources;
pub mod xr_input;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use crate::xr_input::hands::hand_tracking::DisableHandTracking;
use crate::xr_input::oculus_touch::ActionSets;
@@ -23,7 +22,7 @@ use openxr as xr;
use resources::*;
use xr::FormFactor;
use xr_input::controllers::XrControllerType;
use xr_input::hands::emulated::EmulatedHandsPlugin;
use xr_input::hands::emulated::HandEmulationPlugin;
use xr_input::hands::hand_tracking::{HandTrackingData, HandTrackingPlugin};
use xr_input::OpenXrInput;
@@ -228,7 +227,7 @@ impl PluginGroup for DefaultXrPlugins {
.disable::<PipelinedRenderingPlugin>()
.add_before::<RenderPlugin, _>(OpenXrPlugin::default())
.add_after::<OpenXrPlugin, _>(OpenXrInput::new(XrControllerType::OculusTouch))
.add(EmulatedHandsPlugin)
.add(HandEmulationPlugin)
.add(HandTrackingPlugin)
.set(WindowPlugin {
#[cfg(not(target_os = "android"))]

View File

@@ -16,7 +16,6 @@ use crate::xr_input::{
use super::{
actions::XrActionSets,
hands::hand_tracking::HandTrackingData,
trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTrackingRoot},
};
@@ -54,43 +53,38 @@ pub fn draw_gizmos(
Without<OpenXRLeftController>,
Without<OpenXRTrackingRoot>,
)>,
hand_tracking: Option<Res<HandTrackingData>>,
action_sets: Res<XrActionSets>,
) {
if let Some(hand_tracking) = hand_tracking {
let handtracking_ref = hand_tracking.get_ref(&xr_input, &frame_state);
if let Some(joints) = handtracking_ref.get_poses(Hand::Left) {
for joint in joints.inner() {
let trans = Transform::from_rotation(joint.orientation);
gizmos.circle(
joint.position,
trans.forward(),
joint.radius,
Color::ORANGE_RED,
);
}
} else {
info!("left_hand_poses returned None");
}
if let Some(joints) = handtracking_ref.get_poses(Hand::Right) {
for joint in joints.inner() {
let trans = Transform::from_rotation(joint.orientation);
gizmos.circle(
joint.position,
trans.forward(),
joint.radius,
Color::LIME_GREEN,
);
}
return;
}
}
// if let Some(hand_tracking) = hand_tracking {
// let handtracking_ref = hand_tracking.get_ref(&xr_input, &frame_state);
// if let Some(joints) = handtracking_ref.get_poses(Hand::Left) {
// for joint in joints.inner() {
// let trans = Transform::from_rotation(joint.orientation);
// gizmos.circle(
// joint.position,
// trans.forward(),
// joint.radius,
// Color::ORANGE_RED,
// );
// }
// }
// if let Some(joints) = handtracking_ref.get_poses(Hand::Right) {
// for joint in joints.inner() {
// let trans = Transform::from_rotation(joint.orientation);
// gizmos.circle(
// joint.position,
// trans.forward(),
// joint.radius,
// Color::LIME_GREEN,
// );
// }
// return;
// }
// }
//lock frame
let frame_state = *frame_state.lock().unwrap();
//get controller
let controller = oculus_controller.get_ref(&session, &frame_state, &xr_input, &action_sets);
//tracking root?
let mut tracking_transform = &Transform::IDENTITY;
let root = tracking_root_query.get_single();
match root {
Ok(position) => {
@@ -105,7 +99,6 @@ pub fn draw_gizmos(
0.2,
Color::RED,
);
tracking_transform = position.0;
}
Err(_) => info!("too many tracking roots"),
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,286 @@
use bevy::prelude::{
default, Color, Commands, Component, Deref, DerefMut, Entity, Gizmos, Plugin, PostUpdate,
Query, Resource, SpatialBundle, Startup, Transform,
};
use crate::xr_input::{Hand, trackers::OpenXRTracker};
use super::{HandBone, BoneTrackingStatus};
/// add debug renderer for controllers
#[derive(Default)]
pub struct OpenXrHandInput;
impl Plugin for OpenXrHandInput {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_systems(Startup, spawn_hand_entities);
}
}
/// add debug renderer for controllers
#[derive(Default)]
pub struct HandInputDebugRenderer;
impl Plugin for HandInputDebugRenderer {
fn build(&self, app: &mut bevy::prelude::App) {
app.add_systems(PostUpdate, draw_hand_entities);
}
}
#[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,
pub thumb: ThumbResource,
pub index: IndexResource,
pub middle: MiddleResource,
pub ring: RingResource,
pub little: LittleResource,
}
impl Default for HandResource {
fn default() -> Self {
Self {
palm: Entity::PLACEHOLDER,
wrist: Entity::PLACEHOLDER,
thumb: Default::default(),
index: Default::default(),
middle: Default::default(),
ring: Default::default(),
little: Default::default(),
}
}
}
#[derive(Clone, Copy)]
pub struct ThumbResource {
pub metacarpal: Entity,
pub proximal: Entity,
pub distal: Entity,
pub tip: Entity,
}
impl Default for ThumbResource {
fn default() -> Self {
Self {
metacarpal: Entity::PLACEHOLDER,
proximal: Entity::PLACEHOLDER,
distal: Entity::PLACEHOLDER,
tip: Entity::PLACEHOLDER,
}
}
}
#[derive(Clone, Copy)]
pub struct IndexResource {
pub metacarpal: Entity,
pub proximal: Entity,
pub intermediate: Entity,
pub distal: Entity,
pub tip: Entity,
}
impl Default for IndexResource {
fn default() -> Self {
Self {
metacarpal: Entity::PLACEHOLDER,
proximal: Entity::PLACEHOLDER,
intermediate: Entity::PLACEHOLDER,
distal: Entity::PLACEHOLDER,
tip: Entity::PLACEHOLDER,
}
}
}
#[derive(Clone, Copy)]
pub struct MiddleResource {
pub metacarpal: Entity,
pub proximal: Entity,
pub intermediate: Entity,
pub distal: Entity,
pub tip: Entity,
}
impl Default for MiddleResource {
fn default() -> Self {
Self {
metacarpal: Entity::PLACEHOLDER,
proximal: Entity::PLACEHOLDER,
intermediate: Entity::PLACEHOLDER,
distal: Entity::PLACEHOLDER,
tip: Entity::PLACEHOLDER,
}
}
}
#[derive(Clone, Copy)]
pub struct RingResource {
pub metacarpal: Entity,
pub proximal: Entity,
pub intermediate: Entity,
pub distal: Entity,
pub tip: Entity,
}
impl Default for RingResource {
fn default() -> Self {
Self {
metacarpal: Entity::PLACEHOLDER,
proximal: Entity::PLACEHOLDER,
intermediate: Entity::PLACEHOLDER,
distal: Entity::PLACEHOLDER,
tip: Entity::PLACEHOLDER,
}
}
}
#[derive(Clone, Copy)]
pub struct LittleResource {
pub metacarpal: Entity,
pub proximal: Entity,
pub intermediate: Entity,
pub distal: Entity,
pub tip: Entity,
}
impl Default for LittleResource {
fn default() -> Self {
Self {
metacarpal: Entity::PLACEHOLDER,
proximal: Entity::PLACEHOLDER,
intermediate: Entity::PLACEHOLDER,
distal: Entity::PLACEHOLDER,
tip: Entity::PLACEHOLDER,
}
}
}
pub fn spawn_hand_entities(mut commands: Commands) {
let hands = [Hand::Left, Hand::Right];
let bones = HandBone::get_all_bones();
//hand resource
let mut hand_resource = HandsResource { ..default() };
for hand in hands.iter() {
for bone in bones.iter() {
let boneid = commands
.spawn((
SpatialBundle::default(),
bone.clone(),
OpenXRTracker,
hand.clone(),
BoneTrackingStatus::Emulated,
HandBoneRadius(0.1),
))
.id();
match hand {
Hand::Left => match bone {
HandBone::Palm => hand_resource.left.palm = boneid,
HandBone::Wrist => hand_resource.left.wrist = boneid,
HandBone::ThumbMetacarpal => hand_resource.left.thumb.metacarpal = boneid,
HandBone::ThumbProximal => hand_resource.left.thumb.proximal = boneid,
HandBone::ThumbDistal => hand_resource.left.thumb.distal = boneid,
HandBone::ThumbTip => hand_resource.left.thumb.tip = boneid,
HandBone::IndexMetacarpal => hand_resource.left.index.metacarpal = boneid,
HandBone::IndexProximal => hand_resource.left.index.proximal = boneid,
HandBone::IndexIntermediate => hand_resource.left.index.intermediate = boneid,
HandBone::IndexDistal => hand_resource.left.index.distal = boneid,
HandBone::IndexTip => hand_resource.left.index.tip = boneid,
HandBone::MiddleMetacarpal => hand_resource.left.middle.metacarpal = boneid,
HandBone::MiddleProximal => hand_resource.left.middle.proximal = boneid,
HandBone::MiddleIntermediate => hand_resource.left.middle.intermediate = boneid,
HandBone::MiddleDistal => hand_resource.left.middle.distal = boneid,
HandBone::MiddleTip => hand_resource.left.middle.tip = boneid,
HandBone::RingMetacarpal => hand_resource.left.ring.metacarpal = boneid,
HandBone::RingProximal => hand_resource.left.ring.proximal = boneid,
HandBone::RingIntermediate => hand_resource.left.ring.intermediate = boneid,
HandBone::RingDistal => hand_resource.left.ring.distal = boneid,
HandBone::RingTip => hand_resource.left.ring.tip = boneid,
HandBone::LittleMetacarpal => hand_resource.left.little.metacarpal = boneid,
HandBone::LittleProximal => hand_resource.left.little.proximal = boneid,
HandBone::LittleIntermediate => hand_resource.left.little.intermediate = boneid,
HandBone::LittleDistal => hand_resource.left.little.distal = boneid,
HandBone::LittleTip => hand_resource.left.little.tip = boneid,
},
Hand::Right => match bone {
HandBone::Palm => hand_resource.right.palm = boneid,
HandBone::Wrist => hand_resource.right.wrist = boneid,
HandBone::ThumbMetacarpal => hand_resource.right.thumb.metacarpal = boneid,
HandBone::ThumbProximal => hand_resource.right.thumb.proximal = boneid,
HandBone::ThumbDistal => hand_resource.right.thumb.distal = boneid,
HandBone::ThumbTip => hand_resource.right.thumb.tip = boneid,
HandBone::IndexMetacarpal => hand_resource.right.index.metacarpal = boneid,
HandBone::IndexProximal => hand_resource.right.index.proximal = boneid,
HandBone::IndexIntermediate => hand_resource.right.index.intermediate = boneid,
HandBone::IndexDistal => hand_resource.right.index.distal = boneid,
HandBone::IndexTip => hand_resource.right.index.tip = boneid,
HandBone::MiddleMetacarpal => hand_resource.right.middle.metacarpal = boneid,
HandBone::MiddleProximal => hand_resource.right.middle.proximal = boneid,
HandBone::MiddleIntermediate => {
hand_resource.right.middle.intermediate = boneid
}
HandBone::MiddleDistal => hand_resource.right.middle.distal = boneid,
HandBone::MiddleTip => hand_resource.right.middle.tip = boneid,
HandBone::RingMetacarpal => hand_resource.right.ring.metacarpal = boneid,
HandBone::RingProximal => hand_resource.right.ring.proximal = boneid,
HandBone::RingIntermediate => hand_resource.right.ring.intermediate = boneid,
HandBone::RingDistal => hand_resource.right.ring.distal = boneid,
HandBone::RingTip => hand_resource.right.ring.tip = boneid,
HandBone::LittleMetacarpal => hand_resource.right.little.metacarpal = boneid,
HandBone::LittleProximal => hand_resource.right.little.proximal = boneid,
HandBone::LittleIntermediate => {
hand_resource.right.little.intermediate = boneid
}
HandBone::LittleDistal => hand_resource.right.little.distal = boneid,
HandBone::LittleTip => hand_resource.right.little.tip = boneid,
},
}
}
}
commands.insert_resource(hand_resource);
}
#[derive(Debug, Component, DerefMut, Deref)]
pub struct HandBoneRadius(pub f32);
pub fn draw_hand_entities(
mut gizmos: Gizmos,
query: Query<(&Transform, &HandBone, &HandBoneRadius)>,
) {
for (transform, hand_bone, hand_bone_radius) in query.iter() {
let (_, color) = get_bone_gizmo_style(hand_bone);
gizmos.sphere(
transform.translation,
transform.rotation,
hand_bone_radius.0,
color,
);
}
}
pub(crate) fn get_bone_gizmo_style(hand_bone: &HandBone) -> (f32, Color) {
match hand_bone {
HandBone::Palm => (0.01, Color::WHITE),
HandBone::Wrist => (0.01, Color::GRAY),
HandBone::ThumbMetacarpal => (0.01, Color::RED),
HandBone::ThumbProximal => (0.008, Color::RED),
HandBone::ThumbDistal => (0.006, Color::RED),
HandBone::ThumbTip => (0.004, Color::RED),
HandBone::IndexMetacarpal => (0.01, Color::ORANGE),
HandBone::IndexProximal => (0.008, Color::ORANGE),
HandBone::IndexIntermediate => (0.006, Color::ORANGE),
HandBone::IndexDistal => (0.004, Color::ORANGE),
HandBone::IndexTip => (0.002, Color::ORANGE),
HandBone::MiddleMetacarpal => (0.01, Color::YELLOW),
HandBone::MiddleProximal => (0.008, Color::YELLOW),
HandBone::MiddleIntermediate => (0.006, Color::YELLOW),
HandBone::MiddleDistal => (0.004, Color::YELLOW),
HandBone::MiddleTip => (0.002, Color::YELLOW),
HandBone::RingMetacarpal => (0.01, Color::GREEN),
HandBone::RingProximal => (0.008, Color::GREEN),
HandBone::RingIntermediate => (0.006, Color::GREEN),
HandBone::RingDistal => (0.004, Color::GREEN),
HandBone::RingTip => (0.002, Color::GREEN),
HandBone::LittleMetacarpal => (0.01, Color::BLUE),
HandBone::LittleProximal => (0.008, Color::BLUE),
HandBone::LittleIntermediate => (0.006, Color::BLUE),
HandBone::LittleDistal => (0.004, Color::BLUE),
HandBone::LittleTip => (0.002, Color::BLUE),
}
}

View File

@@ -1,20 +1,18 @@
use std::f32::consts::PI;
use bevy::prelude::*;
use openxr::{Action, ActionTy, Binding, HandJoint};
use openxr::{ActionTy, HandJoint};
use super::common::{get_bone_gizmo_style, HandBoneRadius};
use crate::{
resources::{XrInstance, XrSession},
xr_input::{
actions::{
ActionHandednes, ActionType, SetupActionSet, SetupActionSets, XrActionSets, XrBinding,
},
controllers::Touchable,
hand::{get_bone_gizmo_style, HandBoneRadius},
hand_poses::get_simulated_open_hand_transforms,
oculus_touch::ActionSets,
trackers::{OpenXRLeftController, OpenXRRightController, OpenXRTrackingRoot},
Hand, InteractionProfileBindings,
Hand,
},
};
@@ -25,22 +23,16 @@ pub enum TouchValue<T: ActionTy> {
Touched(T),
}
// #[derive(Deref, DerefMut, Resource)]
// pub struct EmulatedHandPoseFunctions {
// pub get_base_pose: Box<dyn Fn(Hand) -> [Transform; 26] + Send + Sync>,
// pub map_data: Box<dyn Fn(Hand) -> [Transform; 26] + Send + Sync>,
// }
pub struct HandEmulationPlugin;
pub struct EmulatedHandsPlugin;
impl Plugin for EmulatedHandsPlugin {
impl Plugin for HandEmulationPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, update_hand_skeleton_from_emulated);
app.add_systems(Startup, setup_hand_emulation_action_set);
}
}
const HAND_ACTION_SET: &'static str = "hand_pose_approx";
const HAND_ACTION_SET: &str = "hand_pose_approx";
fn setup_hand_emulation_action_set(mut action_sets: ResMut<SetupActionSets>) {
let mut action_set = action_sets.add_action_set(HAND_ACTION_SET, "Hand Pose Approximaiton", 0);

View File

@@ -3,12 +3,14 @@ use openxr::{HandTracker, Result, SpaceLocationFlags};
use crate::{
input::XrInput,
resources::{XrFrameState, XrSession},
xr_input::{
hand::HandBoneRadius, hands::HandBone, trackers::OpenXRTrackingRoot, Hand, QuatConv,
hands::HandBone, trackers::OpenXRTrackingRoot, Hand, QuatConv,
Vec3Conv,
},
};
use super::common::HandBoneRadius;
use super::BoneTrackingStatus;
@@ -123,13 +125,35 @@ impl Plugin for HandTrackingPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PreUpdate,
(update_hand_bones).run_if(|dh: Option<Res<DisableHandTracking>>| {
!dh.is_some_and(|v| *v == DisableHandTracking::Both)
}),
(
update_hand_bones.run_if(|dh: Option<Res<DisableHandTracking>>| {
!dh.is_some_and(|v| *v == DisableHandTracking::Both)
}),
update_tracking_state_on_disable,
),
);
}
}
fn update_tracking_state_on_disable(
mut is_off: Local<bool>,
disabled_tracking: Option<Res<DisableHandTracking>>,
mut tracking_states: Query<&mut BoneTrackingStatus>,
) {
if !*is_off
&& disabled_tracking
.as_ref()
.is_some_and(|t| **t == DisableHandTracking::Both)
{
tracking_states
.par_iter_mut()
.for_each(|mut state| *state = BoneTrackingStatus::Emulated);
}
*is_off = disabled_tracking
.as_ref()
.is_some_and(|t| **t == DisableHandTracking::Both);
}
pub fn update_hand_bones(
disabled_tracking: Option<Res<DisableHandTracking>>,
hand_tracking: Option<Res<HandTrackingData>>,

View File

@@ -1,12 +1,20 @@
use bevy::prelude::*;
use bevy::{app::PluginGroupBuilder, prelude::*};
use self::{emulated::HandEmulationPlugin, hand_tracking::HandTrackingPlugin};
pub mod emulated;
pub mod hand_tracking;
pub mod common;
pub struct HandsPlugin;
pub struct XrHandPlugins;
impl Plugin for HandsPlugin {
fn build(&self, app: &mut bevy::prelude::App) {}
impl PluginGroup for XrHandPlugins {
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
.add(HandTrackingPlugin)
.add(HandEmulationPlugin)
.build()
}
}
#[derive(Component, Debug, Clone, Copy, PartialEq)]

View File

@@ -1,7 +1,8 @@
use std::f32::consts::PI;
use bevy::log::info;
use bevy::prelude::{
info, Color, Component, Entity, Event, EventReader, EventWriter, Gizmos, GlobalTransform, Quat,
Color, Component, Entity, Event, EventReader, EventWriter, Gizmos, GlobalTransform, Quat,
Query, Transform, Vec3, With, Without,
};
@@ -45,7 +46,7 @@ impl Default for XRInteractorState {
#[derive(Component)]
pub enum XRSelection {
Empty,
Full(Entity)
Full(Entity),
}
impl Default for XRSelection {
fn default() -> Self {

View File

@@ -1,7 +1,6 @@
pub mod actions;
pub mod controllers;
pub mod debug_gizmos;
pub mod hand;
pub mod hand_poses;
pub mod hands;
pub mod interactions;

View File

@@ -1,17 +1,16 @@
use crate::input::XrInput;
use crate::resources::{XrInstance, XrSession};
use crate::xr_input::controllers::{Handed, Touchable};
use crate::xr_input::controllers::Handed;
use crate::xr_input::Hand;
use bevy::prelude::{Commands, Res, ResMut, Resource};
use openxr::{
Action, ActionSet, AnyGraphics, Binding, FrameState, Haptic, Instance, Path, Posef, Session,
Space, SpaceLocation, SpaceVelocity,
ActionSet, AnyGraphics, FrameState, Instance, Path, Posef, Session, Space, SpaceLocation,
SpaceVelocity,
};
use std::convert::identity;
use std::sync::OnceLock;
use super::actions::{ActionHandednes, XrActionSets, ActionType, SetupActionSets, XrBinding};
use super::actions::{ActionHandednes, ActionType, SetupActionSets, XrActionSets, XrBinding};
pub fn post_action_setup_oculus_controller(
action_sets: Res<XrActionSets>,
@@ -30,34 +29,18 @@ pub fn post_action_setup_oculus_controller(
.unwrap();
controller.grip_space = Some(Handed {
left: grip_action
.create_space(
s.clone(),
left_path,
Posef::IDENTITY,
)
.create_space(s.clone(), left_path, Posef::IDENTITY)
.unwrap(),
right: grip_action
.create_space(
s.clone(),
right_path,
Posef::IDENTITY,
)
.create_space(s.clone(), right_path, Posef::IDENTITY)
.unwrap(),
});
controller.aim_space = Some(Handed {
left: aim_action
.create_space(
s.clone(),
left_path,
Posef::IDENTITY,
)
.create_space(s.clone(), left_path, Posef::IDENTITY)
.unwrap(),
right: aim_action
.create_space(
s.clone(),
right_path,
Posef::IDENTITY,
)
.create_space(s.clone(), right_path, Posef::IDENTITY)
.unwrap(),
})
}
@@ -100,27 +83,51 @@ pub fn subaction_path(hand: Hand) -> Path {
impl OculusControllerRef<'_> {
pub fn grip_space(&self, hand: Hand) -> (SpaceLocation, SpaceVelocity) {
match hand {
Hand::Left => self.oculus_controller.grip_space.as_ref().unwrap().left.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
Hand::Right => self.oculus_controller.grip_space.as_ref().unwrap().right.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
Hand::Left => self
.oculus_controller
.grip_space
.as_ref()
.unwrap()
.left
.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
Hand::Right => self
.oculus_controller
.grip_space
.as_ref()
.unwrap()
.right
.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
}
.unwrap()
}
pub fn aim_space(&self, hand: Hand) -> (SpaceLocation, SpaceVelocity) {
match hand {
Hand::Left => self.oculus_controller.aim_space.as_ref().unwrap().left.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
Hand::Right => self.oculus_controller.aim_space.as_ref().unwrap().right.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
Hand::Left => self
.oculus_controller
.aim_space
.as_ref()
.unwrap()
.left
.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
Hand::Right => self
.oculus_controller
.aim_space
.as_ref()
.unwrap()
.right
.relate(
&self.xr_input.stage,
self.frame_state.predicted_display_time,
),
}
.unwrap()
}

View File

@@ -1,11 +1,11 @@
use bevy::log::info;
use bevy::prelude::{
info, Added, BuildChildren, Commands, Component, Entity, Query, Res, Transform, Vec3, With,
Without,
Added, BuildChildren, Commands, Component, Entity, Query, Res, Transform, Vec3, With, Without,
};
use crate::{
input::XrInput,
resources::{XrFrameState, XrInstance, XrSession},
resources::{XrFrameState, XrSession},
};
use super::{actions::XrActionSets, oculus_touch::OculusController, Hand, QuatConv, Vec3Conv};