Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Porting the server to Bevy #31

Draft
wants to merge 22 commits into
base: dev
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9f4420f
refactor: begin conversion to bevy, do proper frame wait
Schmarni-Dev Dec 14, 2024
da90307
refactor: probably get models mostly working
Schmarni-Dev Dec 15, 2024
3065c95
refactor: absolutly minimal text impl, doesn't yet care about state c…
Schmarni-Dev Dec 15, 2024
6a23dea
refactor: impl audio
Schmarni-Dev Dec 16, 2024
fa0eedd
refactor: very close to compiling, controllers should almost compile
Schmarni-Dev Dec 16, 2024
93d074d
refactor: handtracking
Schmarni-Dev Dec 16, 2024
4e706f6
refactor: compiles!
Schmarni-Dev Dec 16, 2024
e3321c5
refactor: IT RUNS!
Schmarni-Dev Dec 16, 2024
1936792
refactor: get models fully working
Schmarni-Dev Dec 19, 2024
2efdbec
refactor: improve performance a lot
Schmarni-Dev Dec 27, 2024
b1207f8
refactor: add text spawning tracing spans and slightly improve perfor…
Schmarni-Dev Dec 29, 2024
8c23767
refactor fixup after rebase
Schmarni-Dev Dec 29, 2024
ba945b4
refactor: Sleep in parallel while doing independent work
Schmarni-Dev Dec 29, 2024
53741d5
refactor: use minimal plugins
Schmarni-Dev Dec 29, 2024
b46df0a
refactor: use bevy for handling ctrl-c
Schmarni-Dev Dec 29, 2024
1fcb54c
refactor: add optinal support for pipelined rendering
Schmarni-Dev Dec 29, 2024
054109d
refactor: fix error module after rebase and reduce usage of the eyre!…
Schmarni-Dev Dec 31, 2024
a832266
refactor: add text support
Schmarni-Dev Jan 15, 2025
4ea0d60
refactor use bevy_sk material and hands
Schmarni-Dev Jan 17, 2025
18a2d3a
fix: readd smithay commit
technobaboo Jan 16, 2025
90c9447
refactor: clean up code
technobaboo Jan 16, 2025
c62c0b2
refactor: readd Cargo.lock
Schmarni-Dev Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor fixup after rebase
Signed-off-by: Schmarni <[email protected]>
  • Loading branch information
Schmarni-Dev committed Dec 31, 2024

Verified

This commit was signed with the committer’s verified signature.
JounQin JounQin
commit 8c23767a54dcea8c4c036fae70c16b1e38005a13
15 changes: 10 additions & 5 deletions src/nodes/audio.rs
Original file line number Diff line number Diff line change
@@ -121,7 +121,9 @@ impl Sound {
let sound_arc = SOUND_REGISTRY.add(sound);
node.add_aspect_raw(sound_arc.clone());
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)
}
@@ -139,7 +141,9 @@ impl SoundAspect for Sound {
.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(())
}
@@ -149,7 +153,9 @@ impl SoundAspect for Sound {
.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(())
}
@@ -163,8 +169,7 @@ impl Drop for Sound {
}
}

struct AudioInterface;
impl InterfaceAspect for AudioInterface {
impl InterfaceAspect for Interface {
#[doc = "Create a sound node. WAV and MP3 are supported."]
fn create_sound(
_node: Arc<Node>,
4 changes: 2 additions & 2 deletions src/nodes/items/panel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::camera::CameraItemAcceptor;
// use super::camera::CameraItemAcceptor;
use super::{create_item_acceptor_flex, register_item_ui_flex};
use crate::bail;
use crate::core::error::Result;
@@ -469,7 +469,7 @@ impl<B: Backend> Drop for PanelItem<B> {
impl InterfaceAspect for Interface {
#[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<()> {
node.add_aspect(CameraItemAcceptor);
// node.add_aspect(CameraItemAcceptor);
register_item_ui_flex(calling_client, &ITEM_TYPE_INFO_PANEL)
}

105 changes: 17 additions & 88 deletions src/objects/input/sk_controller.rs
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ use bevy::{
pbr::MeshMaterial3d,
prelude::{Children, Commands, Component, Mesh, Query, Res, ResMut, Transform},
scene::SceneRoot,
utils::default,
};
use bevy_mod_openxr::{
helper_traits::{ToQuat, ToVec2, ToVec3},
@@ -96,7 +97,7 @@ fn update_controllers(
if input_node.enabled() {
let world_transform = location;
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)
} else {
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();

// remove the capture when it's removed from captures list
if let Some(capture) = &controller.capture {
if !controller
.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);
}
let distance_calculator = |space: &Arc<Spatial>, _data: &InputDataType, field: &Field| {
Some(field.distance(space, [0.0; 3].into()).abs())
};

let input = controller.input.clone();
controller.capture_manager.update_capture(&input);
controller
.capture_manager
.set_new_capture(&input, distance_calculator);
controller.capture_manager.apply_capture(&input);

// make sure that if something is captured only send input to it
controller.input.captures.clear();
if let Some(capture) = &controller.capture {
controller.input.set_handler_order([capture].into_iter());
controller.input.captures.add_raw(capture);
if controller.capture_manager.capture.is_some() {
return;
}

// send input to all the input handlers that are the closest to the ray as possible
controller.input.set_handler_order(
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(),
);
let sorted_handlers = get_sorted_handlers(&input, distance_calculator);
controller.input.set_handler_order(sorted_handlers.iter());
}
}

@@ -290,7 +219,6 @@ fn spawn_controllers(
input,
handed,
material: OnceCell::new(),
capture: None,
datamap: Default::default(),
space: actions
.pose
@@ -301,6 +229,7 @@ fn spawn_controllers(
)
.unwrap(),
actions,
capture_manager: default(),
},
));
}
@@ -313,10 +242,10 @@ pub struct SkController {
input: Arc<InputMethod>,
handed: HandSide,
material: OnceCell<Handle<DefaultMaterial>>,
capture: Option<Arc<InputHandler>>,
datamap: ControllerDatamap,
space: openxr::Space,
actions: Actions,
capture_manager: CaptureManager,
}
struct Actions {
set: openxr::ActionSet,
116 changes: 32 additions & 84 deletions src/objects/input/sk_hand.rs
Original file line number Diff line number Diff line change
@@ -12,9 +12,7 @@ use crate::objects::{ObjectHandle, SpatialRef};
use crate::DefaultMaterial;
use bevy::app::{Plugin, PostUpdate};
use bevy::asset::{AssetServer, Assets, Handle};
use bevy::prelude::{
Commands, Component, Entity, Gizmos, IntoSystemConfigs as _, Query, Res, ResMut,
};
use bevy::prelude::{Commands, Component, Entity, Gizmos, IntoSystemConfigs as _, Query, Res, ResMut};
use bevy::utils::default;
use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3};
use bevy_mod_openxr::resources::OxrFrameState;
@@ -32,6 +30,8 @@ use std::sync::Arc;
use tracing::error;
use zbus::Connection;

use super::{get_sorted_handlers, CaptureManager};

fn update_joint(joint: &mut Joint, oxr_joint: openxr::HandJointLocation) {
let flags = OxrSpaceLocationFlags(oxr_joint.location_flags);
if flags.pos_valid() && flags.rot_valid() {
@@ -114,88 +114,35 @@ fn update_hands(
hand.datamap.grab_strength = grip_activation(joints);
*hand.input.datamap.lock() = Datamap::from_typed(&hand.datamap).unwrap();
}
// remove the capture when it's removed from captures list
if let Some(capture) = &hand.capture {
if !hand
.input
.capture_requests
.get_valid_contents()
.contains(capture)
{
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);
}
let distance_calculator = |space: &Arc<Spatial>, data: &InputDataType, field: &Field| {
let InputDataType::Hand(hand) = data else {
return None;
};
let thumb_tip_distance = field.distance(space, hand.thumb.tip.position.into());
let index_tip_distance = field.distance(space, hand.index.tip.position.into());
let middle_tip_distance = field.distance(space, hand.middle.tip.position.into());
let ring_tip_distance = field.distance(space, hand.ring.tip.position.into());

Some(
(thumb_tip_distance * 0.3)
+ (index_tip_distance * 0.4)
+ (middle_tip_distance * 0.15)
+ (ring_tip_distance * 0.15),
)
};

// make sure that if something is captured only send input to it
hand.input.captures.clear();
if let Some(capture) = &hand.capture {
hand.input.set_handler_order([capture].into_iter());
hand.input.captures.add_raw(capture);
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;
}

// send input to all the input handlers that are the closest to the ray as possible
hand.input.set_handler_order(
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(),
);
let sorted_handlers = get_sorted_handlers(&hand.input, distance_calculator);
hand.input.set_handler_order(sorted_handlers.iter());
}
}

@@ -268,7 +215,7 @@ fn create_hands(connection: Res<DbusConnection>, session: Res<OxrSession>, mut c
palm_object,
handed,
input,
capture: None,
capture_manager: default(),
datamap: Default::default(),
material: OnceCell::new(),
vis_entity: OnceCell::new(),
@@ -308,16 +255,16 @@ pub struct SkHand {
palm_object: ObjectHandle<SpatialRef>,
handed: HandSide,
input: Arc<InputMethod>,
capture: Option<Arc<InputHandler>>,
datamap: HandDatamap,
material: OnceCell<Handle<DefaultMaterial>>,
vis_entity: OnceCell<Entity>,
hand_tracker: openxr::HandTracker,
capture_manager: CaptureManager,
}
impl SkHand {
fn compare_distance(&self, field: &Field) -> f32 {
let InputDataType::Hand(hand) = &*self.input.data.lock() else {
return INFINITY;
return f32::INFINITY;
};
let spatial = &self.input.spatial;
let thumb_tip_distance = field.distance(spatial, hand.thumb.tip.position.into());
@@ -331,3 +278,4 @@ impl SkHand {
+ (ring_tip_distance * 0.15)
}
}

2 changes: 1 addition & 1 deletion src/objects/mod.rs
Original file line number Diff line number Diff line change
@@ -203,7 +203,7 @@ impl ServerObjects {
eye_pointer.update();
}
}
Some(Inputs::MousePointer(mouse_pointer)) => mouse_pointer.update(),
Some(Inputs::MousePointer(mouse_pointer)) => {}
// Inputs::Controllers((left, right)) => {
// left.update(token);
// right.update(token);