Skip to content

Commit

Permalink
refactor: the rest of the flatland
Browse files Browse the repository at this point in the history
  • Loading branch information
technobaboo committed Dec 12, 2024
1 parent 2217499 commit 2b145e4
Show file tree
Hide file tree
Showing 14 changed files with 1,988 additions and 1,193 deletions.
727 changes: 535 additions & 192 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ map-range = "0.1.2"
ashpd = { version = "0.8.1", features = ["tokio"], default-features = false }
derive_setters = "0.1.6"
derive-where = "1.2.7"
serde = { version = "1.0.216", features = ["derive"] }

[dependencies.stardust-xr-fusion]
git = "https://github.com/StardustXR/core.git"
Expand Down
Binary file modified assets/panel.blend
Binary file not shown.
62 changes: 34 additions & 28 deletions src/close_button.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use crate::toplevel::TOPLEVEL_THICKNESS;
// use crate::toplevel::TOPLEVEL_THICKNESS;
use asteroids::{
custom::{ElementTrait, Transformable},
custom::{ElementTrait, FnWrapper, Transformable},
ValidState,
};
use derive_setters::Setters;
use glam::Quat;
use stardust_xr_fusion::{
core::values::{color::rgba_linear, ResourceID},
core::{
schemas::zbus::Connection,
values::{color::rgba_linear, ResourceID},
},
drawable::{MaterialParameter, Model, ModelPart, ModelPartAspect},
fields::{Field, Shape},
fields::{Field, FieldAspect, Shape},
input::{InputDataType::Pointer, InputHandler},
node::{NodeError, NodeType},
root::FrameInfo,
Expand All @@ -17,50 +21,50 @@ use stardust_xr_molecules::{
input_action::{InputQueue, InputQueueable, SimpleAction},
Exposure,
};
use std::fmt::Debug;

#[derive_where::derive_where(Debug, PartialEq)]
#[derive(Setters)]
#[setters(into, strip_option)]
pub struct ExposureButton<State: ValidState> {
pub transform: Transform,
pub thickness: f32,
pub on_click: Box<dyn Fn(&mut State) + Send + Sync>,
}
impl<State: ValidState> Debug for ExposureButton<State> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ExposureButton")
.field("transform", &self.transform)
.field("thickness", &self.thickness)
.finish()
}
}
impl<State: ValidState> PartialEq for ExposureButton<State> {
fn eq(&self, other: &Self) -> bool {
self.transform == other.transform && self.thickness == other.thickness
}
pub on_click: FnWrapper<dyn Fn(&mut State) + Send + Sync>,
}
impl<State: ValidState> ElementTrait<State> for ExposureButton<State> {
type Inner = ExposureButtonInner;
type Error = NodeError;

fn create_inner(&self, spatial_parent: &SpatialRef) -> Result<Self::Inner, Self::Error> {
fn create_inner(
&self,
spatial_parent: &SpatialRef,
_dbus_conn: &Connection,
) -> Result<Self::Inner, Self::Error> {
ExposureButtonInner::new(spatial_parent, self.transform, self.thickness)
}
fn frame(&self, info: &FrameInfo, inner: &mut Self::Inner) {
inner.frame(info);
}
fn update(&self, old: &Self, state: &mut State, inner: &mut Self::Inner) {
self.apply_transform(old, &inner.model);
self.apply_transform(old, &inner.root);
if inner.exposure.exposure > 1.0 {
(self.on_click)(state);
(self.on_click.0)(state);
}
if self.thickness != old.thickness {
let _ = inner
.field
.set_shape(Shape::Box([1.5 * 0.025, 0.025, self.thickness].into()));
let _ = inner.model.set_local_transform(Transform::from_scale([
0.025,
0.025,
self.thickness,
]));
}
}

fn spatial_aspect(&self, inner: &Self::Inner) -> SpatialRef {
inner.model.clone().as_spatial().as_spatial_ref()
}
}

impl<State: ValidState> Transformable for ExposureButton<State> {
fn transform(&self) -> &Transform {
&self.transform
Expand Down Expand Up @@ -100,12 +104,14 @@ impl ExposureButtonInner {

// compensate for the server not being able to handle scaled fields
let field = Field::create(
&shell,
&root,
Transform::none(),
Shape::Box([1.5 * 0.025, 0.025, thickness].into()),
)?;
field.set_spatial_parent_in_place(parent)?;
field.set_local_transform(Transform::from_scale([1.0; 3]))?;
field.set_relative_transform(
&shell,
Transform::from_translation_rotation([0.0; 3], Quat::IDENTITY),
)?;

let input = InputHandler::create(&shell, Transform::none(), &field)?.queue()?;

Expand All @@ -121,6 +127,7 @@ impl ExposureButtonInner {
}

pub fn frame(&mut self, frame_info: &FrameInfo) -> bool {
self.input.handle_events();
self.distance_action.update(&self.input, &|data| {
data.distance < 0.0
&& match &data.input {
Expand All @@ -135,8 +142,7 @@ impl ExposureButtonInner {
.map(|d| d.distance.abs().powf(1.0 / 2.2))
.sum();
self.exposure.update(frame_info.delta);
self.exposure
.expose(exposure * 2.0 / TOPLEVEL_THICKNESS, frame_info.delta);
self.exposure.expose(exposure * 2.0, frame_info.delta);
self.exposure
.expose_flash(self.distance_action.currently_acting().len() as f32 * 0.25);
if self.exposure.exposure > 1.0 {
Expand Down
1 change: 0 additions & 1 deletion src/flatland.rs

This file was deleted.

79 changes: 79 additions & 0 deletions src/initial_panel_placement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use asteroids::{custom::ElementTrait, ValidState};
use glam::{vec3, Quat, Vec3};
use stardust_xr_fusion::{
core::schemas::zbus::Connection,
node::{NodeError, NodeResult, NodeType},
objects::hmd,
spatial::{Spatial, SpatialAspect, SpatialRef, SpatialRefAspect, Transform},
};
use std::f32::consts::PI;

fn look_direction(direction: Vec3) -> Quat {
let pitch = direction.y.asin();
let yaw = direction.z.atan2(direction.x);
Quat::from_rotation_y(-yaw - PI / 2.0) * Quat::from_rotation_x(pitch)
}

async fn initial_placement(spatial_root: Spatial) -> NodeResult<()> {
let client = spatial_root.client()?;
let Some(hmd) = hmd(&client).await else {
return Err(NodeError::NotAliased);
};
let root = client.get_root();

let (
Ok(Transform {
translation: item_translation,
..
}),
Ok(Transform {
translation: hmd_translation,
..
}),
) = tokio::join!(spatial_root.get_transform(root), hmd.get_transform(root))
else {
return Err(NodeError::NotAliased);
};

// if the distance between the panel item and the client origin is basically nothing, it must be unpositioned
if Vec3::from(item_translation.unwrap()).length_squared() < 0.001 {
println!("launched without a sense of space");
// so we want to position it in front of the user
let _ = spatial_root.set_relative_transform(
&hmd,
Transform::from_translation_rotation(vec3(0.0, 0.0, -0.25), Quat::IDENTITY),
);
return Ok(());
}

// otherwise make the panel look at the user
let look_rotation = look_direction(
(Vec3::from(item_translation.unwrap()) - Vec3::from(hmd_translation.unwrap())).normalize(),
);
let _ = spatial_root.set_relative_transform(root, Transform::from_rotation(look_rotation));

Ok(())
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub struct InitialPanelPlacement;
impl<State: ValidState> ElementTrait<State> for InitialPanelPlacement {
type Inner = Spatial;
type Error = NodeError;

fn create_inner(
&self,
parent_space: &SpatialRef,
_dbus_conn: &Connection,
) -> Result<Self::Inner, Self::Error> {
let spatial = Spatial::create(parent_space, Transform::identity(), false)?;
tokio::task::spawn(initial_placement(spatial.clone()));
Ok(spatial)
}

fn update(&self, _old_decl: &Self, _state: &mut State, _inner: &mut Self::Inner) {}

fn spatial_aspect(&self, inner: &Self::Inner) -> SpatialRef {
inner.clone().as_spatial_ref()
}
}
29 changes: 29 additions & 0 deletions src/initial_positioner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use asteroids::{custom::ElementTrait, ValidState};
use stardust_xr_fusion::{
core::schemas::zbus::Connection,
node::NodeError,
spatial::{Spatial, SpatialAspect, SpatialRef, Transform},
};

#[derive(Debug, PartialEq)]
pub struct InitialPositioner(pub SpatialRef);
impl<State: ValidState> ElementTrait<State> for InitialPositioner {
type Inner = Spatial;
type Error = NodeError;

fn create_inner(
&self,
parent_space: &SpatialRef,
_dbus_conn: &Connection,
) -> Result<Self::Inner, Self::Error> {
let spatial = Spatial::create(parent_space, Transform::identity(), false)?;
spatial.set_relative_transform(&self.0, Transform::identity())?;
Ok(spatial)
}

fn update(&self, _old_decl: &Self, _state: &mut State, _inner: &mut Self::Inner) {}

fn spatial_aspect(&self, inner: &Self::Inner) -> SpatialRef {
inner.clone().as_spatial_ref()
}
}
Loading

0 comments on commit 2b145e4

Please sign in to comment.