initial code
This commit is contained in:
1140
Cargo.lock
generated
Normal file
1140
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
Cargo.toml
Normal file
14
Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "protostar"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.66"
|
||||
glam = { version = "0.22.0", features = ["mint"] }
|
||||
manifest-dir-macros = "0.1.16"
|
||||
mint = "0.5.9"
|
||||
rustc-hash = "1.1.0"
|
||||
stardust-xr-molecules = "0.5.2"
|
||||
tokio = { version = "1.22.0", features = ["full"] }
|
||||
tween = "1.0.1"
|
||||
BIN
res/protostar/default_icon.glb
Executable file
BIN
res/protostar/default_icon.glb
Executable file
Binary file not shown.
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
hard_tabs = true
|
||||
# fn_single_line = true
|
||||
0
src/args.rs
Normal file
0
src/args.rs
Normal file
25
src/main.rs
Normal file
25
src/main.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
mod protostar;
|
||||
|
||||
use manifest_dir_macros::directory_relative_path;
|
||||
use protostar::ProtoStar;
|
||||
use stardust_xr_molecules::fusion::client::Client;
|
||||
use std::{env::args, path::PathBuf, str::FromStr};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() {
|
||||
let (client, event_loop) = Client::connect_with_async_loop().await.unwrap();
|
||||
client.set_base_prefixes(&[directory_relative_path!("res")]);
|
||||
|
||||
let _root = client.wrap_root(ProtoStar::new(
|
||||
&client,
|
||||
PathBuf::from_str(&args().nth(2).unwrap()).unwrap(),
|
||||
0.1,
|
||||
PathBuf::from_str(&args().nth(1).unwrap()).unwrap(),
|
||||
));
|
||||
|
||||
tokio::select! {
|
||||
_ = tokio::signal::ctrl_c() => Ok(()),
|
||||
_ = event_loop => Err(anyhow::anyhow!("Server crashed")),
|
||||
}
|
||||
.unwrap();
|
||||
}
|
||||
87
src/protostar.rs
Normal file
87
src/protostar.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use glam::Quat;
|
||||
use mint::Vector3;
|
||||
use stardust_xr_molecules::{
|
||||
fusion::{
|
||||
client::{Client, LifeCycleHandler, LogicStepInfo},
|
||||
drawable::Model,
|
||||
fields::SphereField,
|
||||
node::NodeType,
|
||||
startup_settings::StartupSettings,
|
||||
},
|
||||
Grabbable,
|
||||
};
|
||||
use std::{path::PathBuf, process::Command};
|
||||
use tween::{QuartInOut, Tweener};
|
||||
|
||||
pub struct ProtoStar {
|
||||
grabbable: Option<Grabbable>,
|
||||
field: SphereField,
|
||||
icon: Model,
|
||||
icon_shrink: Option<Tweener<QuartInOut<f32, f64>>>,
|
||||
size: f32,
|
||||
executable_path: PathBuf,
|
||||
}
|
||||
impl ProtoStar {
|
||||
pub fn new(client: &Client, icon: PathBuf, size: f32, executable_path: PathBuf) -> Self {
|
||||
let field = SphereField::builder()
|
||||
.spatial_parent(client.get_root())
|
||||
.radius(size * 0.5)
|
||||
.build()
|
||||
.unwrap();
|
||||
let grabbable = Grabbable::new(client.get_root(), &field).unwrap();
|
||||
field
|
||||
.set_spatial_parent(grabbable.content_parent())
|
||||
.unwrap();
|
||||
let icon = Model::builder()
|
||||
.spatial_parent(grabbable.content_parent())
|
||||
.resource(&icon)
|
||||
.scale(Vector3::from([size; 3]))
|
||||
.build()
|
||||
.unwrap();
|
||||
ProtoStar {
|
||||
grabbable: Some(grabbable),
|
||||
field,
|
||||
icon,
|
||||
icon_shrink: None,
|
||||
size,
|
||||
executable_path,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl LifeCycleHandler for ProtoStar {
|
||||
fn logic_step(&mut self, info: LogicStepInfo) {
|
||||
if let Some(grabbable) = &mut self.grabbable {
|
||||
grabbable.update();
|
||||
if grabbable.grab_action().actor_stopped() {
|
||||
let startup_settings =
|
||||
StartupSettings::create(&self.field.spatial.client().unwrap()).unwrap();
|
||||
grabbable
|
||||
.content_parent()
|
||||
.set_rotation(
|
||||
Some(&self.field.client().unwrap().get_root()),
|
||||
Quat::IDENTITY,
|
||||
)
|
||||
.unwrap();
|
||||
startup_settings
|
||||
.set_root(grabbable.content_parent())
|
||||
.unwrap();
|
||||
drop(self.grabbable.take());
|
||||
self.icon_shrink = Some(Tweener::new(QuartInOut::new(self.size..=0.0, 0.25)));
|
||||
let future = startup_settings.generate_desktop_startup_id().unwrap();
|
||||
let mut command = Command::new(self.executable_path.clone());
|
||||
tokio::task::spawn(async move {
|
||||
command.env("DESKTOP_STARTUP_ID", future.await.unwrap());
|
||||
command.spawn().unwrap();
|
||||
drop(startup_settings);
|
||||
});
|
||||
}
|
||||
}
|
||||
if let Some(icon_shrink) = &mut self.icon_shrink {
|
||||
if let Some(scale) = icon_shrink.update(info.delta) {
|
||||
self.icon
|
||||
.set_scale(None, Vector3::from([scale; 3]))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user