feat(drawable): set sky
This commit is contained in:
@@ -2,7 +2,7 @@ use std::path::PathBuf;
|
||||
|
||||
pub type ResourceID = Box<dyn ResourceIDTrait + Send + Sync>;
|
||||
|
||||
pub trait ResourceIDTrait {
|
||||
pub trait ResourceIDTrait: Send + Sync {
|
||||
fn get_file(&self, prefixes: &[PathBuf]) -> Option<PathBuf>;
|
||||
}
|
||||
|
||||
|
||||
38
src/main.rs
38
src/main.rs
@@ -4,9 +4,7 @@ mod objects;
|
||||
mod wayland;
|
||||
|
||||
use crate::core::destroy_queue;
|
||||
use crate::nodes::drawable::model::MODELS_TO_DROP;
|
||||
use crate::nodes::drawable::DRAWABLE_REGISTRY;
|
||||
use crate::nodes::{hmd, input};
|
||||
use crate::nodes::{drawable, hmd, input};
|
||||
use crate::objects::input::mouse_pointer::MousePointer;
|
||||
use crate::objects::input::sk_hand::SkHand;
|
||||
use crate::wayland::Wayland;
|
||||
@@ -36,12 +34,11 @@ struct CliArgs {
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let project_dirs = ProjectDirs::from("", "", "stardust").unwrap();
|
||||
let cli_args = Arc::new(CliArgs::parse());
|
||||
let log = ::slog::Logger::root(::slog_stdlog::StdLog.fuse(), slog::o!());
|
||||
slog_stdlog::init()?;
|
||||
|
||||
let project_dirs = ProjectDirs::from("", "", "stardust").unwrap();
|
||||
|
||||
let mut stereokit = Settings::default()
|
||||
.app_name("Stardust XR")
|
||||
.overlay_app(cli_args.overlay)
|
||||
@@ -56,18 +53,12 @@ fn main() -> Result<()> {
|
||||
.expect("StereoKit failed to initialize");
|
||||
println!("Init StereoKit");
|
||||
|
||||
// Skytex/light stuff
|
||||
{
|
||||
let skytex_path = project_dirs.config_dir().join("skytex.hdr");
|
||||
if let Some((tex, light)) = skytex_path
|
||||
.exists()
|
||||
.then(|| {
|
||||
Texture::from_cubemap_equirectangular(
|
||||
&stereokit,
|
||||
skytex_path.to_str().unwrap(),
|
||||
true,
|
||||
100,
|
||||
)
|
||||
})
|
||||
.then(|| Texture::from_cubemap_equirectangular(&stereokit, &skytex_path, true, 100))
|
||||
.flatten()
|
||||
{
|
||||
stereokit.set_skytex(&tex);
|
||||
@@ -104,29 +95,26 @@ fn main() -> Result<()> {
|
||||
let mut wayland = Wayland::new(log)?;
|
||||
println!("Stardust ready!");
|
||||
stereokit.run(
|
||||
|draw_ctx| {
|
||||
hmd::frame(&stereokit);
|
||||
wayland.frame(&stereokit);
|
||||
|sk, draw_ctx| {
|
||||
hmd::frame(sk);
|
||||
wayland.frame(sk);
|
||||
destroy_queue::clear();
|
||||
|
||||
nodes::root::Root::logic_step(stereokit.time_elapsed());
|
||||
for drawable in DRAWABLE_REGISTRY.get_valid_contents() {
|
||||
drawable.draw(&stereokit, draw_ctx);
|
||||
}
|
||||
MODELS_TO_DROP.lock().clear();
|
||||
nodes::root::Root::logic_step(sk.time_elapsed());
|
||||
drawable::draw(sk, draw_ctx);
|
||||
|
||||
if let Some(mouse_pointer) = &mouse_pointer {
|
||||
mouse_pointer.update(&stereokit);
|
||||
mouse_pointer.update(sk);
|
||||
}
|
||||
if let Some(hands) = &mut hands {
|
||||
hands[0].update(&stereokit);
|
||||
hands[1].update(&stereokit);
|
||||
hands[0].update(sk);
|
||||
hands[1].update(sk);
|
||||
}
|
||||
input::process_input();
|
||||
|
||||
wayland.make_context_current();
|
||||
},
|
||||
|| {
|
||||
|_| {
|
||||
println!("Cleanly shut down StereoKit");
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1,19 +1,60 @@
|
||||
pub mod model;
|
||||
|
||||
use super::Node;
|
||||
use crate::core::{client::Client, registry::Registry};
|
||||
use std::sync::Arc;
|
||||
use stereokit::{lifecycle::DrawContext, StereoKit};
|
||||
|
||||
pub trait Drawable: Send + Sync {
|
||||
fn draw(&self, sk: &StereoKit, draw_ctx: &DrawContext);
|
||||
}
|
||||
|
||||
pub static DRAWABLE_REGISTRY: Registry<dyn Drawable> = Registry::new();
|
||||
use crate::core::client::Client;
|
||||
use anyhow::Result;
|
||||
use parking_lot::Mutex;
|
||||
use std::{path::PathBuf, str::FromStr, sync::Arc};
|
||||
use stereokit::{lifecycle::DrawContext, texture::Texture, StereoKit};
|
||||
|
||||
pub fn create_interface(client: &Arc<Client>) {
|
||||
let node = Node::create(client, "", "drawable", false);
|
||||
node.add_local_signal("createModelFromFile", model::create_from_file);
|
||||
node.add_local_signal("createModelFromResource", model::create_from_resource);
|
||||
node.add_local_signal("setSkyFile", set_sky_file_flex);
|
||||
node.add_to_scenegraph();
|
||||
}
|
||||
|
||||
pub fn draw(sk: &mut StereoKit, draw_ctx: &DrawContext) {
|
||||
model::draw_all(sk, draw_ctx);
|
||||
|
||||
let new_skytex = QUEUED_SKYTEX.lock().take();
|
||||
let mut new_skylight = QUEUED_SKYLIGHT.lock().take();
|
||||
let same_file = new_skytex == new_skylight;
|
||||
|
||||
if let Some(skytex) = new_skytex {
|
||||
if let Some((skytex, skylight)) =
|
||||
Texture::from_cubemap_equirectangular(sk, &skytex, true, i32::MAX)
|
||||
{
|
||||
sk.set_skytex(&skytex);
|
||||
if same_file {
|
||||
sk.set_skylight(&skylight);
|
||||
new_skylight = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(skylight) = new_skylight {
|
||||
if let Some((_, skylight)) =
|
||||
Texture::from_cubemap_equirectangular(sk, &skylight, true, i32::MAX)
|
||||
{
|
||||
sk.set_skylight(&skylight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QUEUED_SKYLIGHT: Mutex<Option<PathBuf>> = Mutex::new(None);
|
||||
static QUEUED_SKYTEX: Mutex<Option<PathBuf>> = Mutex::new(None);
|
||||
|
||||
fn set_sky_file_flex(_node: &Node, _calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
|
||||
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?;
|
||||
let path = PathBuf::from_str(flex_vec.index(0)?.get_str()?)?;
|
||||
path.metadata()?;
|
||||
if flex_vec.idx(1).as_bool() {
|
||||
QUEUED_SKYTEX.lock().replace(path.clone());
|
||||
}
|
||||
if flex_vec.idx(2).as_bool() {
|
||||
QUEUED_SKYLIGHT.lock().replace(path);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
use super::{Drawable, Node};
|
||||
use super::Node;
|
||||
use crate::core::client::Client;
|
||||
use crate::core::registry::Registry;
|
||||
use crate::core::resource::{NamespacedResourceID, ResourceID};
|
||||
use crate::nodes::drawable::DRAWABLE_REGISTRY;
|
||||
use crate::nodes::spatial::{get_spatial_parent_flex, Spatial};
|
||||
use anyhow::{anyhow, bail, ensure, Result};
|
||||
use flexbuffers::FlexBufferType;
|
||||
@@ -24,9 +23,9 @@ use stereokit::render::RenderLayer;
|
||||
use stereokit::texture::Texture;
|
||||
use stereokit::StereoKit;
|
||||
|
||||
pub static MODEL_REGISTRY: Registry<Model> = Registry::new();
|
||||
static MODEL_REGISTRY: Registry<Model> = Registry::new();
|
||||
lazy_static! {
|
||||
pub static ref MODELS_TO_DROP: Mutex<Vec<SendWrapper<SKModel>>> = Default::default();
|
||||
static ref MODELS_TO_DROP: Mutex<Vec<SendWrapper<SKModel>>> = Default::default();
|
||||
}
|
||||
|
||||
pub enum MaterialParameter {
|
||||
@@ -62,7 +61,6 @@ impl Model {
|
||||
};
|
||||
node.add_local_signal("setMaterialParameter", Model::set_material_parameter);
|
||||
let model_arc = MODEL_REGISTRY.add(model);
|
||||
DRAWABLE_REGISTRY.add_raw(&(model_arc.clone() as Arc<dyn Drawable>));
|
||||
let _ = model_arc.pending_model_path.set(
|
||||
model_arc
|
||||
.resource_id
|
||||
@@ -104,8 +102,7 @@ impl Model {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Drawable for Model {
|
||||
|
||||
fn draw(&self, sk: &StereoKit, draw_ctx: &DrawContext) {
|
||||
let sk_model = self
|
||||
.sk_model
|
||||
@@ -162,7 +159,12 @@ impl Drop for Model {
|
||||
MODELS_TO_DROP.lock().push(model);
|
||||
}
|
||||
MODEL_REGISTRY.remove(self);
|
||||
DRAWABLE_REGISTRY.remove(self);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_all(sk: &StereoKit, draw_ctx: &DrawContext) {
|
||||
for model in MODEL_REGISTRY.get_valid_contents() {
|
||||
model.draw(sk, draw_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user