feat: play space
This commit is contained in:
@@ -10,6 +10,7 @@ use crate::objects::input::eye_pointer::EyePointer;
|
|||||||
use crate::objects::input::mouse_pointer::MousePointer;
|
use crate::objects::input::mouse_pointer::MousePointer;
|
||||||
use crate::objects::input::sk_controller::SkController;
|
use crate::objects::input::sk_controller::SkController;
|
||||||
use crate::objects::input::sk_hand::SkHand;
|
use crate::objects::input::sk_hand::SkHand;
|
||||||
|
use crate::objects::play_space::PlaySpace;
|
||||||
|
|
||||||
use self::core::eventloop::EventLoop;
|
use self::core::eventloop::EventLoop;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
@@ -173,6 +174,8 @@ fn main() {
|
|||||||
sk.input_hand_visible(Handed::Right, false);
|
sk.input_hand_visible(Handed::Right, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let play_space = sk.world_has_bounds().then(|| PlaySpace::new().ok()).flatten();
|
||||||
|
|
||||||
let (event_stop_tx, event_stop_rx) = oneshot::channel::<()>();
|
let (event_stop_tx, event_stop_rx) = oneshot::channel::<()>();
|
||||||
let (info_sender, info_receiver) = oneshot::channel::<EventLoopInfo>();
|
let (info_sender, info_receiver) = oneshot::channel::<EventLoopInfo>();
|
||||||
let event_thread = std::thread::Builder::new()
|
let event_thread = std::thread::Builder::new()
|
||||||
@@ -241,6 +244,9 @@ fn main() {
|
|||||||
if let Some(eye_pointer) = &eye_pointer {
|
if let Some(eye_pointer) = &eye_pointer {
|
||||||
eye_pointer.update(sk);
|
eye_pointer.update(sk);
|
||||||
}
|
}
|
||||||
|
if let Some(play_space) = &play_space {
|
||||||
|
play_space.update(sk);
|
||||||
|
}
|
||||||
input::process_input();
|
input::process_input();
|
||||||
nodes::root::Root::send_frame_events(sk.time_elapsed_unscaled());
|
nodes::root::Root::send_frame_events(sk.time_elapsed_unscaled());
|
||||||
adaptive_sleep(
|
adaptive_sleep(
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ pub fn mask_matches(mask_map_lesser: &Mask, mask_map_greater: &Mask) -> bool {
|
|||||||
|
|
||||||
pub struct Mask(pub Vec<u8>);
|
pub struct Mask(pub Vec<u8>);
|
||||||
impl Mask {
|
impl Mask {
|
||||||
|
pub fn from_struct<T: Default + Serialize>() -> Self {
|
||||||
|
let mut serializer = flexbuffers::FlexbufferSerializer::new();
|
||||||
|
T::default().serialize(&mut serializer).unwrap();
|
||||||
|
Mask(serializer.take_buffer())
|
||||||
|
}
|
||||||
pub fn get_mask(&self) -> Result<flexbuffers::MapReader<&[u8]>> {
|
pub fn get_mask(&self) -> Result<flexbuffers::MapReader<&[u8]>> {
|
||||||
flexbuffers::Reader::get_root(self.0.as_slice())
|
flexbuffers::Reader::get_root(self.0.as_slice())
|
||||||
.map_err(|_| eyre!("Mask is not a valid flexbuffer"))?
|
.map_err(|_| eyre!("Mask is not a valid flexbuffer"))?
|
||||||
@@ -182,7 +187,7 @@ pub struct PulseReceiver {
|
|||||||
pub mask: Mask,
|
pub mask: Mask,
|
||||||
}
|
}
|
||||||
impl PulseReceiver {
|
impl PulseReceiver {
|
||||||
pub fn add_to(node: &Arc<Node>, field: Arc<Field>, mask: Mask) -> Result<()> {
|
pub fn add_to(node: &Arc<Node>, field: Arc<Field>, mask: Mask) -> Result<Arc<PulseReceiver>> {
|
||||||
ensure!(
|
ensure!(
|
||||||
node.spatial.get().is_some(),
|
node.spatial.get().is_some(),
|
||||||
"Internal: Node does not have a spatial attached!"
|
"Internal: Node does not have a spatial attached!"
|
||||||
@@ -199,8 +204,8 @@ impl PulseReceiver {
|
|||||||
for sender in PULSE_SENDER_REGISTRY.get_valid_contents() {
|
for sender in PULSE_SENDER_REGISTRY.get_valid_contents() {
|
||||||
sender.handle_new_receiver(&receiver);
|
sender.handle_new_receiver(&receiver);
|
||||||
}
|
}
|
||||||
let _ = node.pulse_receiver.set(receiver);
|
let _ = node.pulse_receiver.set(receiver.clone());
|
||||||
Ok(())
|
Ok(receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_data(&self, uid: &str, data: Vec<u8>) -> Result<()> {
|
pub fn send_data(&self, uid: &str, data: Vec<u8>) -> Result<()> {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ pub struct BoxField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BoxField {
|
impl BoxField {
|
||||||
pub fn add_to(node: &Arc<Node>, size: Vector3<f32>) -> Result<()> {
|
pub fn add_to(node: &Arc<Node>, size: Vector3<f32>) -> Result<Arc<Field>> {
|
||||||
ensure!(
|
ensure!(
|
||||||
node.spatial.get().is_some(),
|
node.spatial.get().is_some(),
|
||||||
"Internal: Node does not have a spatial attached!"
|
"Internal: Node does not have a spatial attached!"
|
||||||
@@ -31,8 +31,9 @@ impl BoxField {
|
|||||||
};
|
};
|
||||||
box_field.add_field_methods(node);
|
box_field.add_field_methods(node);
|
||||||
node.add_local_signal("set_size", BoxField::set_size_flex);
|
node.add_local_signal("set_size", BoxField::set_size_flex);
|
||||||
let _ = node.field.set(Arc::new(Field::Box(box_field)));
|
let field = Arc::new(Field::Box(box_field));
|
||||||
Ok(())
|
let _ = node.field.set(field.clone());
|
||||||
|
Ok(field)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_size(&self, size: Vector3<f32>) {
|
pub fn set_size(&self, size: Vector3<f32>) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
mod r#box;
|
pub mod r#box;
|
||||||
mod cylinder;
|
mod cylinder;
|
||||||
mod sphere;
|
mod sphere;
|
||||||
pub mod torus;
|
mod torus;
|
||||||
|
|
||||||
use self::cylinder::{create_cylinder_field_flex, CylinderField};
|
use self::cylinder::{create_cylinder_field_flex, CylinderField};
|
||||||
use self::r#box::{create_box_field_flex, BoxField};
|
use self::r#box::{create_box_field_flex, BoxField};
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod input;
|
pub mod input;
|
||||||
|
pub mod play_space;
|
||||||
|
|||||||
50
src/objects/play_space.rs
Normal file
50
src/objects/play_space.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use color_eyre::eyre::Result;
|
||||||
|
use glam::Mat4;
|
||||||
|
use mint::Vector2;
|
||||||
|
use nanoid::nanoid;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use stereokit::StereoKitMultiThread;
|
||||||
|
|
||||||
|
use crate::{nodes::{spatial::Spatial, data::{PulseReceiver, Mask}, Node, fields::{Field, r#box::BoxField}}, core::client::INTERNAL_CLIENT};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
struct PlaySpaceMap {
|
||||||
|
play_space: (),
|
||||||
|
size: Vector2<f32>,
|
||||||
|
}
|
||||||
|
impl Default for PlaySpaceMap {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { play_space: (), size: [0.0; 2].into() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PlaySpace {
|
||||||
|
_node: Arc<Node>,
|
||||||
|
spatial: Arc<Spatial>,
|
||||||
|
field: Arc<Field>,
|
||||||
|
_pulse_rx: Arc<PulseReceiver>,
|
||||||
|
}
|
||||||
|
impl PlaySpace {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let node = Node::create(&INTERNAL_CLIENT, "", &nanoid!(), false).add_to_scenegraph()?;
|
||||||
|
let spatial = Spatial::add_to(&node, None, Mat4::IDENTITY, false)?;
|
||||||
|
let field = BoxField::add_to(&node, [0.0;3].into())?;
|
||||||
|
|
||||||
|
let pulse_rx = PulseReceiver::add_to(&node, field.clone(), Mask::from_struct::<PlaySpaceMap>())?;
|
||||||
|
|
||||||
|
Ok(PlaySpace {
|
||||||
|
_node: node,
|
||||||
|
spatial,
|
||||||
|
field,
|
||||||
|
_pulse_rx: pulse_rx,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn update(&self, sk: &impl StereoKitMultiThread) {
|
||||||
|
let pose = sk.world_get_bounds_pose();
|
||||||
|
self.spatial.set_local_transform(Mat4::from_rotation_translation(pose.orientation, pose.position));
|
||||||
|
let Field::Box(box_field) = self.field.as_ref() else {return};
|
||||||
|
box_field.set_size([sk.world_get_bounds_size().x, 0.0, sk.world_get_bounds_size().y].into());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user