refactor fixup after rebase
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -121,7 +121,9 @@ impl Sound {
|
|||||||
let sound_arc = SOUND_REGISTRY.add(sound);
|
let sound_arc = SOUND_REGISTRY.add(sound);
|
||||||
node.add_aspect_raw(sound_arc.clone());
|
node.add_aspect_raw(sound_arc.clone());
|
||||||
if let Some(sender) = SPAWN_SOUND_SENDER.get() {
|
if let Some(sender) = SPAWN_SOUND_SENDER.get() {
|
||||||
sender.send(sound_arc.clone())?;
|
sender
|
||||||
|
.send(sound_arc.clone())
|
||||||
|
.map_err(|_| eyre!("Unable to Spawn Audio Node"))?;
|
||||||
}
|
}
|
||||||
Ok(sound_arc)
|
Ok(sound_arc)
|
||||||
}
|
}
|
||||||
@@ -139,7 +141,9 @@ impl SoundAspect for Sound {
|
|||||||
.get()
|
.get()
|
||||||
.and_then(|s| Some((s, *sound.entity.get()?)))
|
.and_then(|s| Some((s, *sound.entity.get()?)))
|
||||||
{
|
{
|
||||||
sender.send((entity, SoundAction::Play))?
|
sender
|
||||||
|
.send((entity, SoundAction::Play))
|
||||||
|
.map_err(|_| eyre!("Unable to Play Audio"))?
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -149,7 +153,9 @@ impl SoundAspect for Sound {
|
|||||||
.get()
|
.get()
|
||||||
.and_then(|s| Some((s, *sound.entity.get()?)))
|
.and_then(|s| Some((s, *sound.entity.get()?)))
|
||||||
{
|
{
|
||||||
sender.send((entity, SoundAction::Stop))?
|
sender
|
||||||
|
.send((entity, SoundAction::Stop))
|
||||||
|
.map_err(|_| eyre!("Unable to Stop Audio"))?
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -163,8 +169,7 @@ impl Drop for Sound {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AudioInterface;
|
impl InterfaceAspect for Interface {
|
||||||
impl InterfaceAspect for AudioInterface {
|
|
||||||
#[doc = "Create a sound node. WAV and MP3 are supported."]
|
#[doc = "Create a sound node. WAV and MP3 are supported."]
|
||||||
fn create_sound(
|
fn create_sound(
|
||||||
_node: Arc<Node>,
|
_node: Arc<Node>,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use super::camera::CameraItemAcceptor;
|
// use super::camera::CameraItemAcceptor;
|
||||||
use super::{create_item_acceptor_flex, register_item_ui_flex};
|
use super::{create_item_acceptor_flex, register_item_ui_flex};
|
||||||
use crate::bail;
|
use crate::bail;
|
||||||
use crate::core::error::Result;
|
use crate::core::error::Result;
|
||||||
@@ -469,7 +469,7 @@ impl<B: Backend> Drop for PanelItem<B> {
|
|||||||
impl InterfaceAspect for Interface {
|
impl InterfaceAspect for Interface {
|
||||||
#[doc = "Register this client to manage the items of a certain type and create default 3D UI for them."]
|
#[doc = "Register this client to manage the items of a certain type and create default 3D UI for them."]
|
||||||
fn register_panel_item_ui(node: Arc<Node>, calling_client: Arc<Client>) -> Result<()> {
|
fn register_panel_item_ui(node: Arc<Node>, calling_client: Arc<Client>) -> Result<()> {
|
||||||
node.add_aspect(CameraItemAcceptor);
|
// node.add_aspect(CameraItemAcceptor);
|
||||||
register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_PANEL)
|
register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_PANEL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use bevy::{
|
|||||||
pbr::MeshMaterial3d,
|
pbr::MeshMaterial3d,
|
||||||
prelude::{Children, Commands, Component, Mesh, Query, Res, ResMut, Transform},
|
prelude::{Children, Commands, Component, Mesh, Query, Res, ResMut, Transform},
|
||||||
scene::SceneRoot,
|
scene::SceneRoot,
|
||||||
|
utils::default,
|
||||||
};
|
};
|
||||||
use bevy_mod_openxr::{
|
use bevy_mod_openxr::{
|
||||||
helper_traits::{ToQuat, ToVec2, ToVec3},
|
helper_traits::{ToQuat, ToVec2, ToVec3},
|
||||||
@@ -96,7 +97,7 @@ fn update_controllers(
|
|||||||
if input_node.enabled() {
|
if input_node.enabled() {
|
||||||
let world_transform = location;
|
let world_transform = location;
|
||||||
if let Some(mat) = controller.material.get().and_then(|v| mats.get_mut(v)) {
|
if let Some(mat) = controller.material.get().and_then(|v| mats.get_mut(v)) {
|
||||||
mat.base_color = if controller.capture.is_none() {
|
mat.base_color = if controller.capture_manager.capture.is_none() {
|
||||||
LinearRgba::rgb(1.0, 1.0, 1.0)
|
LinearRgba::rgb(1.0, 1.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
LinearRgba::rgb(0.0, 1.0, 0.75)
|
LinearRgba::rgb(0.0, 1.0, 0.75)
|
||||||
@@ -132,95 +133,23 @@ fn update_controllers(
|
|||||||
*controller.input.datamap.lock() = Datamap::from_typed(&controller.datamap).unwrap();
|
*controller.input.datamap.lock() = Datamap::from_typed(&controller.datamap).unwrap();
|
||||||
|
|
||||||
// remove the capture when it's removed from captures list
|
// remove the capture when it's removed from captures list
|
||||||
if let Some(capture) = &controller.capture {
|
let distance_calculator = |space: &Arc<Spatial>, _data: &InputDataType, field: &Field| {
|
||||||
if !controller
|
Some(field.distance(space, [0.0; 3].into()).abs())
|
||||||
.input
|
};
|
||||||
.capture_requests
|
|
||||||
.get_valid_contents()
|
|
||||||
.contains(capture)
|
|
||||||
{
|
|
||||||
controller.capture.take();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add the capture that's the closest if we don't have one
|
|
||||||
if controller.capture.is_none() {
|
|
||||||
controller.capture = controller
|
|
||||||
.input
|
|
||||||
.capture_requests
|
|
||||||
.get_valid_contents()
|
|
||||||
.into_iter()
|
|
||||||
.map(|handler| {
|
|
||||||
(
|
|
||||||
handler.clone(),
|
|
||||||
handler
|
|
||||||
.field
|
|
||||||
.distance(&controller.input.spatial, [0.0; 3].into())
|
|
||||||
.abs(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.reduce(|(handlers_a, distance_a), (handlers_b, distance_b)| {
|
|
||||||
if distance_a < distance_b {
|
|
||||||
(handlers_a, distance_a)
|
|
||||||
} else {
|
|
||||||
(handlers_b, distance_b)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|(rx, _)| rx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure that if something is captured only send input to it
|
let input = controller.input.clone();
|
||||||
controller.input.captures.clear();
|
controller.capture_manager.update_capture(&input);
|
||||||
if let Some(capture) = &controller.capture {
|
controller
|
||||||
controller.input.set_handler_order([capture].into_iter());
|
.capture_manager
|
||||||
controller.input.captures.add_raw(capture);
|
.set_new_capture(&input, distance_calculator);
|
||||||
|
controller.capture_manager.apply_capture(&input);
|
||||||
|
|
||||||
|
if controller.capture_manager.capture.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send input to all the input handlers that are the closest to the ray as possible
|
let sorted_handlers = get_sorted_handlers(&input, distance_calculator);
|
||||||
controller.input.set_handler_order(
|
controller.input.set_handler_order(sorted_handlers.iter());
|
||||||
INPUT_HANDLER_REGISTRY
|
|
||||||
.get_valid_contents()
|
|
||||||
.into_iter()
|
|
||||||
// filter out all the disabled handlers
|
|
||||||
.filter(|handler| {
|
|
||||||
let Some(node) = handler.spatial.node() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
node.enabled()
|
|
||||||
})
|
|
||||||
// filter out all the fields with disabled handlers
|
|
||||||
.filter(|handler| {
|
|
||||||
let Some(node) = handler.field.spatial.node() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
node.enabled()
|
|
||||||
})
|
|
||||||
// get the unsigned distance to the handler's field (unsigned so giant fields won't always eat input)
|
|
||||||
.map(|handler| {
|
|
||||||
(
|
|
||||||
vec![handler.clone()],
|
|
||||||
handler
|
|
||||||
.field
|
|
||||||
.distance(&controller.input.spatial, [0.0; 3].into())
|
|
||||||
.abs(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
// now collect all handlers that are same distance if they're the closest
|
|
||||||
.reduce(|(mut handlers_a, distance_a), (handlers_b, distance_b)| {
|
|
||||||
if (distance_a - distance_b).abs() < 0.001 {
|
|
||||||
// distance is basically the same (within 1mm)
|
|
||||||
handlers_a.extend(handlers_b);
|
|
||||||
(handlers_a, distance_a)
|
|
||||||
} else if distance_a < distance_b {
|
|
||||||
(handlers_a, distance_a)
|
|
||||||
} else {
|
|
||||||
(handlers_b, distance_b)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|(rx, _)| rx)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.iter(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +219,6 @@ fn spawn_controllers(
|
|||||||
input,
|
input,
|
||||||
handed,
|
handed,
|
||||||
material: OnceCell::new(),
|
material: OnceCell::new(),
|
||||||
capture: None,
|
|
||||||
datamap: Default::default(),
|
datamap: Default::default(),
|
||||||
space: actions
|
space: actions
|
||||||
.pose
|
.pose
|
||||||
@@ -301,6 +229,7 @@ fn spawn_controllers(
|
|||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
actions,
|
actions,
|
||||||
|
capture_manager: default(),
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -313,10 +242,10 @@ pub struct SkController {
|
|||||||
input: Arc<InputMethod>,
|
input: Arc<InputMethod>,
|
||||||
handed: HandSide,
|
handed: HandSide,
|
||||||
material: OnceCell<Handle<DefaultMaterial>>,
|
material: OnceCell<Handle<DefaultMaterial>>,
|
||||||
capture: Option<Arc<InputHandler>>,
|
|
||||||
datamap: ControllerDatamap,
|
datamap: ControllerDatamap,
|
||||||
space: openxr::Space,
|
space: openxr::Space,
|
||||||
actions: Actions,
|
actions: Actions,
|
||||||
|
capture_manager: CaptureManager,
|
||||||
}
|
}
|
||||||
struct Actions {
|
struct Actions {
|
||||||
set: openxr::ActionSet,
|
set: openxr::ActionSet,
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ use crate::objects::{ObjectHandle, SpatialRef};
|
|||||||
use crate::DefaultMaterial;
|
use crate::DefaultMaterial;
|
||||||
use bevy::app::{Plugin, PostUpdate};
|
use bevy::app::{Plugin, PostUpdate};
|
||||||
use bevy::asset::{AssetServer, Assets, Handle};
|
use bevy::asset::{AssetServer, Assets, Handle};
|
||||||
use bevy::prelude::{
|
use bevy::prelude::{Commands, Component, Entity, Gizmos, IntoSystemConfigs as _, Query, Res, ResMut};
|
||||||
Commands, Component, Entity, Gizmos, IntoSystemConfigs as _, Query, Res, ResMut,
|
|
||||||
};
|
|
||||||
use bevy::utils::default;
|
use bevy::utils::default;
|
||||||
use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3};
|
use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3};
|
||||||
use bevy_mod_openxr::resources::OxrFrameState;
|
use bevy_mod_openxr::resources::OxrFrameState;
|
||||||
@@ -32,6 +30,8 @@ use std::sync::Arc;
|
|||||||
use tracing::error;
|
use tracing::error;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
|
use super::{get_sorted_handlers, CaptureManager};
|
||||||
|
|
||||||
fn update_joint(joint: &mut Joint, oxr_joint: openxr::HandJointLocation) {
|
fn update_joint(joint: &mut Joint, oxr_joint: openxr::HandJointLocation) {
|
||||||
let flags = OxrSpaceLocationFlags(oxr_joint.location_flags);
|
let flags = OxrSpaceLocationFlags(oxr_joint.location_flags);
|
||||||
if flags.pos_valid() && flags.rot_valid() {
|
if flags.pos_valid() && flags.rot_valid() {
|
||||||
@@ -114,88 +114,35 @@ fn update_hands(
|
|||||||
hand.datamap.grab_strength = grip_activation(joints);
|
hand.datamap.grab_strength = grip_activation(joints);
|
||||||
*hand.input.datamap.lock() = Datamap::from_typed(&hand.datamap).unwrap();
|
*hand.input.datamap.lock() = Datamap::from_typed(&hand.datamap).unwrap();
|
||||||
}
|
}
|
||||||
// remove the capture when it's removed from captures list
|
let distance_calculator = |space: &Arc<Spatial>, data: &InputDataType, field: &Field| {
|
||||||
if let Some(capture) = &hand.capture {
|
let InputDataType::Hand(hand) = data else {
|
||||||
if !hand
|
return None;
|
||||||
.input
|
};
|
||||||
.capture_requests
|
let thumb_tip_distance = field.distance(space, hand.thumb.tip.position.into());
|
||||||
.get_valid_contents()
|
let index_tip_distance = field.distance(space, hand.index.tip.position.into());
|
||||||
.contains(capture)
|
let middle_tip_distance = field.distance(space, hand.middle.tip.position.into());
|
||||||
{
|
let ring_tip_distance = field.distance(space, hand.ring.tip.position.into());
|
||||||
hand.capture.take();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add the capture that's the closest if we don't have one
|
|
||||||
if hand.capture.is_none() {
|
|
||||||
hand.capture = hand
|
|
||||||
.input
|
|
||||||
.capture_requests
|
|
||||||
.get_valid_contents()
|
|
||||||
.into_iter()
|
|
||||||
.map(|handler| (handler.clone(), hand.compare_distance(&handler.field).abs()))
|
|
||||||
.reduce(|(handlers_a, distance_a), (handlers_b, distance_b)| {
|
|
||||||
if distance_a < distance_b {
|
|
||||||
(handlers_a, distance_a)
|
|
||||||
} else {
|
|
||||||
(handlers_b, distance_b)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|(rx, _)| rx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure that if something is captured only send input to it
|
Some(
|
||||||
hand.input.captures.clear();
|
(thumb_tip_distance * 0.3)
|
||||||
if let Some(capture) = &hand.capture {
|
+ (index_tip_distance * 0.4)
|
||||||
hand.input.set_handler_order([capture].into_iter());
|
+ (middle_tip_distance * 0.15)
|
||||||
hand.input.captures.add_raw(capture);
|
+ (ring_tip_distance * 0.15),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let input = hand.input.clone();
|
||||||
|
hand.capture_manager.update_capture(&input);
|
||||||
|
hand.capture_manager
|
||||||
|
.set_new_capture(&input, distance_calculator);
|
||||||
|
hand.capture_manager.apply_capture(&input);
|
||||||
|
|
||||||
|
if hand.capture_manager.capture.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send input to all the input handlers that are the closest to the ray as possible
|
let sorted_handlers = get_sorted_handlers(&hand.input, distance_calculator);
|
||||||
hand.input.set_handler_order(
|
hand.input.set_handler_order(sorted_handlers.iter());
|
||||||
INPUT_HANDLER_REGISTRY
|
|
||||||
.get_valid_contents()
|
|
||||||
.into_iter()
|
|
||||||
// filter out all the disabled handlers
|
|
||||||
.filter(|handler| {
|
|
||||||
let Some(node) = handler.spatial.node() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
node.enabled()
|
|
||||||
})
|
|
||||||
// filter out all the fields with disabled handlers
|
|
||||||
.filter(|handler| {
|
|
||||||
let Some(node) = handler.field.spatial.node() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
node.enabled()
|
|
||||||
})
|
|
||||||
// get the unsigned distance to the handler's field (unsigned so giant fields won't always eat input)
|
|
||||||
.map(|handler| {
|
|
||||||
(
|
|
||||||
vec![handler.clone()],
|
|
||||||
hand.compare_distance(&handler.field).abs(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
// .inspect(|(_, result)| {
|
|
||||||
// dbg!(result);
|
|
||||||
// })
|
|
||||||
// now collect all handlers that are same distance if they're the closest
|
|
||||||
.reduce(|(mut handlers_a, distance_a), (handlers_b, distance_b)| {
|
|
||||||
if (distance_a - distance_b).abs() < 0.001 {
|
|
||||||
// distance is basically the same (within 1mm)
|
|
||||||
handlers_a.extend(handlers_b);
|
|
||||||
(handlers_a, distance_a)
|
|
||||||
} else if distance_a < distance_b {
|
|
||||||
(handlers_a, distance_a)
|
|
||||||
} else {
|
|
||||||
(handlers_b, distance_b)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|(rx, _)| rx)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.iter(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +215,7 @@ fn create_hands(connection: Res<DbusConnection>, session: Res<OxrSession>, mut c
|
|||||||
palm_object,
|
palm_object,
|
||||||
handed,
|
handed,
|
||||||
input,
|
input,
|
||||||
capture: None,
|
capture_manager: default(),
|
||||||
datamap: Default::default(),
|
datamap: Default::default(),
|
||||||
material: OnceCell::new(),
|
material: OnceCell::new(),
|
||||||
vis_entity: OnceCell::new(),
|
vis_entity: OnceCell::new(),
|
||||||
@@ -308,16 +255,16 @@ pub struct SkHand {
|
|||||||
palm_object: ObjectHandle<SpatialRef>,
|
palm_object: ObjectHandle<SpatialRef>,
|
||||||
handed: HandSide,
|
handed: HandSide,
|
||||||
input: Arc<InputMethod>,
|
input: Arc<InputMethod>,
|
||||||
capture: Option<Arc<InputHandler>>,
|
|
||||||
datamap: HandDatamap,
|
datamap: HandDatamap,
|
||||||
material: OnceCell<Handle<DefaultMaterial>>,
|
material: OnceCell<Handle<DefaultMaterial>>,
|
||||||
vis_entity: OnceCell<Entity>,
|
vis_entity: OnceCell<Entity>,
|
||||||
hand_tracker: openxr::HandTracker,
|
hand_tracker: openxr::HandTracker,
|
||||||
|
capture_manager: CaptureManager,
|
||||||
}
|
}
|
||||||
impl SkHand {
|
impl SkHand {
|
||||||
fn compare_distance(&self, field: &Field) -> f32 {
|
fn compare_distance(&self, field: &Field) -> f32 {
|
||||||
let InputDataType::Hand(hand) = &*self.input.data.lock() else {
|
let InputDataType::Hand(hand) = &*self.input.data.lock() else {
|
||||||
return INFINITY;
|
return f32::INFINITY;
|
||||||
};
|
};
|
||||||
let spatial = &self.input.spatial;
|
let spatial = &self.input.spatial;
|
||||||
let thumb_tip_distance = field.distance(spatial, hand.thumb.tip.position.into());
|
let thumb_tip_distance = field.distance(spatial, hand.thumb.tip.position.into());
|
||||||
@@ -331,3 +278,4 @@ impl SkHand {
|
|||||||
+ (ring_tip_distance * 0.15)
|
+ (ring_tip_distance * 0.15)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ impl ServerObjects {
|
|||||||
eye_pointer.update();
|
eye_pointer.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Inputs::MousePointer(mouse_pointer)) => mouse_pointer.update(),
|
Some(Inputs::MousePointer(mouse_pointer)) => {}
|
||||||
// Inputs::Controllers((left, right)) => {
|
// Inputs::Controllers((left, right)) => {
|
||||||
// left.update(token);
|
// left.update(token);
|
||||||
// right.update(token);
|
// right.update(token);
|
||||||
|
|||||||
Reference in New Issue
Block a user