feat: various minor improvements
Signed-off-by: Schmarni <marnistromer@gmail.com>
This commit is contained in:
@@ -24,8 +24,8 @@ path = "src/main.rs"
|
||||
default = []
|
||||
wayland = ["dep:smithay", "dep:wayland-scanner", "dep:wayland-backend"]
|
||||
profile_tokio = ["dep:console-subscriber", "tokio/tracing"]
|
||||
profile_app = ["dep:tracing-tracy", "bevy/trace_tracy"]
|
||||
change_tracking = ["bevy/track_location"]
|
||||
profile_app = ["dep:tracing-tracy", "bevy/trace_tracy", "bevy/trace"]
|
||||
bevy_debugging = ["bevy/bevy_remote", "bevy/track_location"]
|
||||
|
||||
[package.metadata.appimage]
|
||||
auto_link = true
|
||||
@@ -64,7 +64,7 @@ color-eyre = { version = "0.6.3", default-features = false }
|
||||
clap = { version = "4.5.13", features = ["derive"] }
|
||||
console-subscriber = { version = "0.4.0", optional = true }
|
||||
thiserror = "2.0.9"
|
||||
tracing = "0.1.40"
|
||||
tracing = { version = "0.1.40", features = ["release_max_level_warn"] }
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||
tracing-tracy = { version = "0.11.1", optional = true }
|
||||
|
||||
@@ -79,7 +79,7 @@ mint = "0.5.9"
|
||||
tokio = { version = "1.39.2", features = ["rt-multi-thread", "signal", "time"] }
|
||||
|
||||
# bevy
|
||||
bevy = { version = "0.16", features = ["wayland", "bevy_remote", "mp3", "wav"] }
|
||||
bevy = { version = "0.16", features = ["wayland", "mp3", "wav"] }
|
||||
bevy_mod_xr = "0.3"
|
||||
bevy_mod_openxr = "0.3"
|
||||
# bevy_sk.git = "https://github.com/MalekiRe/bevy_sk"
|
||||
|
||||
@@ -21,8 +21,6 @@ use bevy::gizmos::GizmoPlugin;
|
||||
use bevy::gltf::GltfPlugin;
|
||||
use bevy::input::InputPlugin;
|
||||
use bevy::pbr::PbrPlugin;
|
||||
use bevy::remote::RemotePlugin;
|
||||
use bevy::remote::http::RemoteHttpPlugin;
|
||||
use bevy::render::{RenderDebugFlags, RenderPlugin};
|
||||
use bevy::scene::ScenePlugin;
|
||||
use bevy::text::FontLoader;
|
||||
@@ -378,7 +376,10 @@ fn bevy_loop(
|
||||
app.add_schedule(pre_frame_wait);
|
||||
app.insert_resource(ClearColor(Color::BLACK.with_alpha(0.0)));
|
||||
app.insert_resource(ObjectRegistryRes(object_registry));
|
||||
app.add_plugins((RemotePlugin::default(), RemoteHttpPlugin::default()));
|
||||
#[cfg(feature = "bevy_debugging")]
|
||||
{
|
||||
app.add_plugins((RemotePlugin::default(), RemoteHttpPlugin::default()));
|
||||
}
|
||||
// the Stardust server plugins
|
||||
// infra plugins
|
||||
app.add_plugins(EntityHandlePlugin);
|
||||
|
||||
@@ -27,7 +27,7 @@ pub struct LinesNodePlugin;
|
||||
|
||||
impl Plugin for LinesNodePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, (build_line_mesh, update_visibillity).chain());
|
||||
app.add_systems(Update, (build_line_mesh/* , update_visibillity */).chain());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ impl Plugin for ModelNodePlugin {
|
||||
app.add_systems(Update, load_models);
|
||||
app.add_systems(
|
||||
PostUpdate,
|
||||
(gen_model_parts, apply_materials, update_visibillity).chain(),
|
||||
(gen_model_parts, apply_materials/* , update_visibillity */).chain(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
BevyMaterial,
|
||||
core::{
|
||||
bevy_channel::{BevyChannel, BevyChannelReader},
|
||||
client::Client,
|
||||
@@ -9,10 +10,12 @@ use crate::{
|
||||
resource::get_resource_file,
|
||||
},
|
||||
nodes::{
|
||||
drawable::XAlign, spatial::{Spatial, SpatialNode}, Node
|
||||
}, BevyMaterial,
|
||||
Node,
|
||||
drawable::XAlign,
|
||||
spatial::{Spatial, SpatialNode},
|
||||
},
|
||||
};
|
||||
use bevy::{platform::collections::HashMap, prelude::*};
|
||||
use bevy::{platform::collections::HashMap, prelude::*, render::mesh::MeshAabb};
|
||||
use bevy_mesh_text_3d::{
|
||||
Align, Attrs, MeshTextPlugin, Settings as FontSettings, generate_meshes,
|
||||
text_glyphs::TextGlyphs,
|
||||
@@ -40,25 +43,7 @@ impl Plugin for TextNodePlugin {
|
||||
|
||||
SPAWN_TEXT.init(app);
|
||||
app.init_resource::<MaterialRegistry>();
|
||||
app.add_systems(Update, (spawn_text, update_visibillity).chain());
|
||||
}
|
||||
}
|
||||
|
||||
fn update_visibillity(mut cmds: Commands) {
|
||||
for text in TEXT_REGISTRY.get_valid_contents().into_iter() {
|
||||
let Some(entity) = text.entity.lock().as_deref().copied() else {
|
||||
continue;
|
||||
};
|
||||
match text.spatial.node().map(|n| n.enabled()).unwrap_or(false) {
|
||||
true => {
|
||||
cmds.entity(entity)
|
||||
.insert_recursive::<Children>(Visibility::Visible);
|
||||
}
|
||||
false => {
|
||||
cmds.entity(entity)
|
||||
.insert_recursive::<Children>(Visibility::Hidden);
|
||||
}
|
||||
}
|
||||
app.add_systems(Update, spawn_text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,15 +119,25 @@ fn spawn_text(
|
||||
if let Some(db) = old_db {
|
||||
mem::swap(font_settings.font_system.db_mut(), db);
|
||||
}
|
||||
let Ok(meshes) = char_meshes.inspect_err(|err| error!("unable to create text meshes: {err}"))
|
||||
let Ok(char_meshes) =
|
||||
char_meshes.inspect_err(|err| error!("unable to create text meshes: {err}"))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let dist = meshes
|
||||
.iter()
|
||||
.fold(f32::MAX, |dist, v| dist.min(v.transform.translation.x));
|
||||
let dist = char_meshes.iter().fold(f32::MAX, |dist, v| {
|
||||
dist.min(
|
||||
v.transform.translation.x
|
||||
- meshes
|
||||
.get(&v.mesh)
|
||||
.unwrap()
|
||||
.compute_aabb()
|
||||
.unwrap_or_default()
|
||||
.half_extents
|
||||
.x,
|
||||
)
|
||||
});
|
||||
// TODO: text align
|
||||
let letters = meshes
|
||||
let letters = char_meshes
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
cmds.spawn((
|
||||
|
||||
@@ -6,6 +6,8 @@ mod method;
|
||||
mod pointer;
|
||||
mod tip;
|
||||
|
||||
use bevy::tasks::ComputeTaskPool;
|
||||
use bevy::tasks::ParallelSlice;
|
||||
pub use handler::*;
|
||||
pub use method::*;
|
||||
use tracing::debug_span;
|
||||
@@ -120,55 +122,60 @@ pub fn process_input() {
|
||||
};
|
||||
node.enabled()
|
||||
});
|
||||
for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() {
|
||||
let _span = debug_span!("handle input handler").entered();
|
||||
for method_alias in handler.method_aliases.get_aliases() {
|
||||
method_alias.set_enabled(false);
|
||||
}
|
||||
INPUT_HANDLER_REGISTRY
|
||||
.get_valid_contents()
|
||||
.into_iter()
|
||||
.par_splat_map(ComputeTaskPool::get(), None, |_, handlers| {
|
||||
for handler in handlers {
|
||||
let _span = debug_span!("handle input handler").entered();
|
||||
for method_alias in handler.method_aliases.get_aliases() {
|
||||
method_alias.set_enabled(false);
|
||||
}
|
||||
|
||||
let Some(handler_node) = handler.spatial.node() else {
|
||||
continue;
|
||||
};
|
||||
if !handler_node.enabled() {
|
||||
continue;
|
||||
}
|
||||
if let Some(handler_field_node) = handler.field.spatial.node() {
|
||||
if !handler_field_node.enabled() {
|
||||
continue;
|
||||
let Some(handler_node) = handler.spatial.node() else {
|
||||
continue;
|
||||
};
|
||||
if !handler_node.enabled() {
|
||||
continue;
|
||||
}
|
||||
if let Some(handler_field_node) = handler.field.spatial.node() {
|
||||
if !handler_field_node.enabled() {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let ser_span = debug_span!("serializing input").entered();
|
||||
let (methods, datas) = methods
|
||||
.clone()
|
||||
// filter out methods without the handler in their handler order
|
||||
.filter(|a| {
|
||||
a.handler_order
|
||||
.lock()
|
||||
.iter()
|
||||
.any(|h| h.ptr_eq(&Arc::downgrade(&handler)))
|
||||
})
|
||||
// filter out methods without the proper alias
|
||||
.filter_map(|m| {
|
||||
Some((
|
||||
handler
|
||||
.method_aliases
|
||||
.get_from_original_node(m.spatial.node.clone())?,
|
||||
m,
|
||||
))
|
||||
})
|
||||
// make sure the input method alias is enabled
|
||||
.inspect(|(a, _)| {
|
||||
a.set_enabled(true);
|
||||
})
|
||||
// serialize the data
|
||||
.map(|(a, m)| (a.clone(), m.serialize(a.get_id(), &handler)))
|
||||
.unzip::<_, _, Vec<_>, Vec<_>>();
|
||||
drop(ser_span);
|
||||
|
||||
let _span = debug_span!("client input").entered();
|
||||
let _ = input_handler_client::input(&handler_node, &methods, &datas);
|
||||
}
|
||||
};
|
||||
|
||||
let ser_span = debug_span!("serializing input").entered();
|
||||
let (methods, datas) = methods
|
||||
.clone()
|
||||
// filter out methods without the handler in their handler order
|
||||
.filter(|a| {
|
||||
a.handler_order
|
||||
.lock()
|
||||
.iter()
|
||||
.any(|h| h.ptr_eq(&Arc::downgrade(&handler)))
|
||||
})
|
||||
// filter out methods without the proper alias
|
||||
.filter_map(|m| {
|
||||
Some((
|
||||
handler
|
||||
.method_aliases
|
||||
.get_from_original_node(m.spatial.node.clone())?,
|
||||
m,
|
||||
))
|
||||
})
|
||||
// make sure the input method alias is enabled
|
||||
.inspect(|(a, _)| {
|
||||
a.set_enabled(true);
|
||||
})
|
||||
// serialize the data
|
||||
.map(|(a, m)| (a.clone(), m.serialize(a.get_id(), &handler)))
|
||||
.unzip::<_, _, Vec<_>, Vec<_>>();
|
||||
drop(ser_span);
|
||||
|
||||
let _span = debug_span!("client input").entered();
|
||||
let _ = input_handler_client::input(&handler_node, &methods, &datas);
|
||||
}
|
||||
});
|
||||
for method in methods {
|
||||
method.cull_capture_attempts();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use mint::Vector3;
|
||||
use parking_lot::Mutex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::{Arc, OnceLock, Weak};
|
||||
use std::{f32, ptr};
|
||||
|
||||
@@ -32,17 +33,42 @@ impl Plugin for SpatialNodePlugin {
|
||||
}
|
||||
|
||||
fn update_spatial_nodes(
|
||||
mut query: Query<(&mut BevyTransform, &SpatialNode, Option<&ChildOf>)>,
|
||||
mut query: Query<(
|
||||
&mut BevyTransform,
|
||||
&SpatialNode,
|
||||
Option<&ChildOf>,
|
||||
&mut Visibility,
|
||||
)>,
|
||||
parent_query: Query<&GlobalTransform>,
|
||||
) {
|
||||
query
|
||||
.par_iter_mut()
|
||||
.for_each(|(mut transform, spatial_node, child_of)| {
|
||||
.for_each(|(mut transform, spatial_node, child_of, mut vis)| {
|
||||
let _span = debug_span!("updating spatial node").entered();
|
||||
let Some(spatial) = spatial_node.0.upgrade() else {
|
||||
// should we despawn the entity?
|
||||
return;
|
||||
};
|
||||
let mat4 = spatial.global_transform();
|
||||
if spatial
|
||||
.node()
|
||||
.is_some_and(|v| !v.enabled.load(Ordering::Relaxed))
|
||||
{
|
||||
if !matches!(*vis, Visibility::Hidden) {
|
||||
*vis = Visibility::Hidden;
|
||||
}
|
||||
return;
|
||||
}
|
||||
let mat4 =
|
||||
debug_span!("getting global transform").in_scope(|| spatial.global_transform());
|
||||
let (scale, _, _) = mat4.to_scale_rotation_translation();
|
||||
match (*vis, scale == Vec3::ZERO) {
|
||||
(Visibility::Inherited | Visibility::Visible, true) => {
|
||||
*vis = Visibility::Hidden;
|
||||
}
|
||||
(Visibility::Hidden, false) => {
|
||||
*vis = Visibility::Inherited;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match child_of {
|
||||
Some(child_of) => {
|
||||
let Ok(parent) = parent_query.get(child_of.0) else {
|
||||
@@ -60,7 +86,7 @@ fn update_spatial_nodes(
|
||||
}
|
||||
|
||||
#[derive(Clone, Component, Debug)]
|
||||
#[require(BevyTransform)]
|
||||
#[require(BevyTransform, Visibility)]
|
||||
pub struct SpatialNode(pub Weak<Spatial>);
|
||||
|
||||
stardust_xr_server_codegen::codegen_spatial_protocol!();
|
||||
|
||||
@@ -39,6 +39,7 @@ use std::{
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
};
|
||||
use tracing::instrument;
|
||||
use zbus::Connection;
|
||||
pub struct ControllerPlugin;
|
||||
const CURSOR_MODEL_PATH: &str = "/tmp/stardust_server/models/cursor.glb";
|
||||
@@ -152,9 +153,11 @@ fn update(
|
||||
controllers.right.set_enabled(false);
|
||||
return;
|
||||
};
|
||||
session
|
||||
.sync_actions(&[ActiveActionSet::new(&actions.set)])
|
||||
.unwrap();
|
||||
debug_span!("sync actions").in_scope(|| {
|
||||
session
|
||||
.sync_actions(&[ActiveActionSet::new(&actions.set)])
|
||||
.unwrap();
|
||||
});
|
||||
let time = state.predicted_display_time;
|
||||
// stupid bevy gltf loading issue (rotated 180 degrees on the y axis)
|
||||
controllers
|
||||
@@ -299,6 +302,7 @@ impl SkController {
|
||||
space: None,
|
||||
})
|
||||
}
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub fn set_enabled(&self, enabled: bool) {
|
||||
if let Some(node) = self.input.spatial.node() {
|
||||
node.set_enabled(enabled);
|
||||
@@ -321,6 +325,7 @@ impl SkController {
|
||||
let Some(space) = self.space.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let _span = debug_span!("locate space").entered();
|
||||
let Ok(location) = session
|
||||
.locate_space(space, &ref_space, time)
|
||||
.inspect_err(|err| error!("error while locating controller space: {err}"))
|
||||
@@ -333,6 +338,7 @@ impl SkController {
|
||||
| SpaceLocationFlags::ORIENTATION_VALID
|
||||
| SpaceLocationFlags::ORIENTATION_TRACKED,
|
||||
);
|
||||
drop(_span);
|
||||
self.set_enabled(enabled);
|
||||
if enabled {
|
||||
let world_transform = Mat4::from(Affine3A::from(location.pose.to_xr_pose()));
|
||||
@@ -377,6 +383,7 @@ impl SkController {
|
||||
.map(|v| v.current_state)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
let _span = debug_span!("apply datamap").entered();
|
||||
self.datamap = ControllerDatamap {
|
||||
select: get(session, path, &actions.trigger),
|
||||
middle: get(session, path, &actions.stick_click) as u32 as f32,
|
||||
@@ -385,6 +392,7 @@ impl SkController {
|
||||
scroll: get(session, path, &actions.stick).to_vec2(),
|
||||
};
|
||||
*self.input.datamap.lock() = Datamap::from_typed(&self.datamap).unwrap();
|
||||
drop(_span);
|
||||
|
||||
let distance_calculator = |space: &Arc<Spatial>, _data: &InputDataType, field: &Field| {
|
||||
Some(field.distance(space, [0.0; 3].into()).abs())
|
||||
|
||||
Reference in New Issue
Block a user