refactor fixup after rebase

Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
Schmarni
2024-12-29 21:33:27 +01:00
parent b1207f8174
commit 8c23767a54
5 changed files with 62 additions and 180 deletions

View File

@@ -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>,

View File

@@ -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)
} }

View File

@@ -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,

View File

@@ -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)
} }
} }

View File

@@ -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);