fix(model): no panic on material change
This commit is contained in:
@@ -9,7 +9,6 @@ use color_eyre::eyre::{eyre, Result};
|
||||
use glam::{vec3, Vec4Swizzles};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use send_wrapper::SendWrapper;
|
||||
use stardust_xr::values::ResourceID;
|
||||
|
||||
use std::ops::DerefMut;
|
||||
@@ -25,7 +24,7 @@ pub struct Sound {
|
||||
|
||||
volume: f32,
|
||||
pending_audio_path: PathBuf,
|
||||
sk_sound: OnceCell<SendWrapper<SkSound>>,
|
||||
sk_sound: OnceCell<SkSound>,
|
||||
instance: Mutex<Option<SoundInst>>,
|
||||
stop: Mutex<Option<()>>,
|
||||
play: Mutex<Option<()>>,
|
||||
@@ -54,9 +53,9 @@ impl Sound {
|
||||
}
|
||||
|
||||
fn update(&self) {
|
||||
let sound = self.sk_sound.get_or_init(|| {
|
||||
SendWrapper::new(SkSound::from_file(self.pending_audio_path.clone()).unwrap())
|
||||
});
|
||||
let sound = self
|
||||
.sk_sound
|
||||
.get_or_init(|| SkSound::from_file(self.pending_audio_path.clone()).unwrap());
|
||||
if self.stop.lock().take().is_some() {
|
||||
if let Some(instance) = self.instance.lock().take() {
|
||||
instance.stop();
|
||||
|
||||
@@ -9,7 +9,7 @@ use glam::{Mat4, Vec2, Vec3};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use rustc_hash::FxHashMap;
|
||||
use send_wrapper::SendWrapper;
|
||||
|
||||
use stardust_xr::values::ResourceID;
|
||||
use stereokit_rust::material::Transparency;
|
||||
use stereokit_rust::maths::Bounds;
|
||||
@@ -21,8 +21,12 @@ use std::sync::{Arc, Weak};
|
||||
|
||||
use super::{MaterialParameter, ModelAspect, ModelPartAspect, MODEL_PART_ASPECT_ALIAS_INFO};
|
||||
|
||||
pub struct MaterialWrapper(pub Material);
|
||||
unsafe impl Send for MaterialWrapper {}
|
||||
unsafe impl Sync for MaterialWrapper {}
|
||||
|
||||
static MODEL_REGISTRY: Registry<Model> = Registry::new();
|
||||
static HOLDOUT_MATERIAL: OnceCell<Arc<SendWrapper<Material>>> = OnceCell::new();
|
||||
static HOLDOUT_MATERIAL: OnceCell<Arc<MaterialWrapper>> = OnceCell::new();
|
||||
|
||||
impl MaterialParameter {
|
||||
fn apply_to_material(&self, client: &Client, material: &Material, parameter_name: &str) {
|
||||
@@ -72,7 +76,7 @@ pub struct ModelPart {
|
||||
space: Arc<Spatial>,
|
||||
model: Weak<Model>,
|
||||
pending_material_parameters: Mutex<FxHashMap<String, MaterialParameter>>,
|
||||
pending_material_replacement: Mutex<Option<Arc<SendWrapper<Material>>>>,
|
||||
pending_material_replacement: Mutex<Option<Arc<MaterialWrapper>>>,
|
||||
aliases: AliasList,
|
||||
}
|
||||
impl ModelPart {
|
||||
@@ -81,7 +85,7 @@ impl ModelPart {
|
||||
let mut mat = Material::copy(Material::unlit());
|
||||
mat.transparency(Transparency::None);
|
||||
mat.color_tint(Color128::BLACK_TRANSPARENT);
|
||||
Arc::new(SendWrapper::new(mat))
|
||||
Arc::new(MaterialWrapper(mat))
|
||||
});
|
||||
|
||||
let nodes = sk_model.get_nodes();
|
||||
@@ -151,7 +155,7 @@ impl ModelPart {
|
||||
Some(model_part)
|
||||
}
|
||||
|
||||
pub fn replace_material(&self, replacement: Arc<SendWrapper<Material>>) {
|
||||
pub fn replace_material(&self, replacement: Arc<MaterialWrapper>) {
|
||||
self.pending_material_replacement
|
||||
.lock()
|
||||
.replace(replacement);
|
||||
@@ -195,7 +199,7 @@ impl ModelPart {
|
||||
};
|
||||
|
||||
if let Some(material_replacement) = self.pending_material_replacement.lock().take() {
|
||||
part.material(&**material_replacement);
|
||||
part.material(&material_replacement.0);
|
||||
}
|
||||
|
||||
// todo: find all materials with identical parameters and batch them into 1 material again
|
||||
|
||||
@@ -45,12 +45,12 @@ impl InputMethod {
|
||||
handler_field_aliases: AliasList::default(),
|
||||
handler_order: Mutex::new(Vec::new()),
|
||||
};
|
||||
<InputMethod as InputMethodRefAspect>::add_node_members(node);
|
||||
<InputMethod as InputMethodAspect>::add_node_members(node);
|
||||
for handler in INPUT_HANDLER_REGISTRY.get_valid_contents() {
|
||||
method.handle_new_handler(&handler);
|
||||
}
|
||||
let method = INPUT_METHOD_REGISTRY.add(method);
|
||||
<InputMethod as InputMethodRefAspect>::add_node_members(node);
|
||||
<InputMethod as InputMethodAspect>::add_node_members(node);
|
||||
node.add_aspect_raw(method.clone());
|
||||
Ok(method)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ use crate::{
|
||||
core::{client::Client, registry::Registry, scenegraph::MethodResponseSender},
|
||||
create_interface,
|
||||
nodes::{
|
||||
drawable::{model::ModelPart, shaders::UNLIT_SHADER_BYTES},
|
||||
drawable::{
|
||||
model::{MaterialWrapper, ModelPart},
|
||||
shaders::UNLIT_SHADER_BYTES,
|
||||
},
|
||||
items::TypeInfo,
|
||||
spatial::{Spatial, Transform},
|
||||
Message, Node,
|
||||
@@ -17,7 +20,7 @@ use lazy_static::lazy_static;
|
||||
use mint::{ColumnMatrix4, Vector2};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
use send_wrapper::SendWrapper;
|
||||
|
||||
use stardust_xr::schemas::flex::{deserialize, serialize};
|
||||
use std::sync::Arc;
|
||||
use stereokit_rust::{
|
||||
@@ -30,6 +33,10 @@ use stereokit_rust::{
|
||||
};
|
||||
use tracing::error;
|
||||
|
||||
pub struct TexWrapper(pub Tex);
|
||||
unsafe impl Send for TexWrapper {}
|
||||
unsafe impl Sync for TexWrapper {}
|
||||
|
||||
stardust_xr_server_codegen::codegen_item_camera_protocol!();
|
||||
lazy_static! {
|
||||
pub(super) static ref ITEM_TYPE_INFO_CAMERA: TypeInfo = TypeInfo {
|
||||
@@ -53,8 +60,8 @@ struct FrameInfo {
|
||||
pub struct CameraItem {
|
||||
space: Arc<Spatial>,
|
||||
frame_info: Mutex<FrameInfo>,
|
||||
sk_tex: OnceCell<SendWrapper<Tex>>,
|
||||
sk_mat: OnceCell<Arc<SendWrapper<Material>>>,
|
||||
sk_tex: OnceCell<TexWrapper>,
|
||||
sk_mat: OnceCell<Arc<MaterialWrapper>>,
|
||||
applied_to: Registry<ModelPart>,
|
||||
apply_to: Registry<ModelPart>,
|
||||
}
|
||||
@@ -120,7 +127,7 @@ impl CameraItem {
|
||||
pub fn update(&self, token: &MainThreadToken) {
|
||||
let frame_info = self.frame_info.lock();
|
||||
let sk_tex = self.sk_tex.get_or_init(|| {
|
||||
SendWrapper::new(Tex::gen_color(
|
||||
TexWrapper(Tex::gen_color(
|
||||
Color128::default(),
|
||||
frame_info.px_size.x as i32,
|
||||
frame_info.px_size.y as i32,
|
||||
@@ -130,12 +137,12 @@ impl CameraItem {
|
||||
});
|
||||
let sk_mat = self
|
||||
.sk_mat
|
||||
.get_or_try_init(|| -> Result<Arc<SendWrapper<Material>>> {
|
||||
.get_or_try_init(|| -> Result<Arc<MaterialWrapper>> {
|
||||
let shader = Shader::from_memory(&UNLIT_SHADER_BYTES)?;
|
||||
let mut mat = Material::new(&shader, None);
|
||||
mat.get_all_param_info().set_texture("diffuse", &**sk_tex);
|
||||
mat.get_all_param_info().set_texture("diffuse", &sk_tex.0);
|
||||
mat.transparency(Transparency::Blend);
|
||||
Ok(Arc::new(SendWrapper::new(mat)))
|
||||
Ok(Arc::new(MaterialWrapper(mat)))
|
||||
});
|
||||
let Ok(sk_mat) = sk_mat else {
|
||||
error!("unable to make camera item stereokit texture");
|
||||
@@ -148,7 +155,7 @@ impl CameraItem {
|
||||
if !self.applied_to.is_empty() {
|
||||
Renderer::render_to(
|
||||
token,
|
||||
&**sk_tex,
|
||||
&sk_tex.0,
|
||||
self.space.global_transform(),
|
||||
frame_info.proj_matrix,
|
||||
None,
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
use super::{state::WaylandState, utils::get_data};
|
||||
use crate::{
|
||||
core::{delta::Delta, destroy_queue, registry::Registry},
|
||||
nodes::drawable::{model::ModelPart, shaders::PANEL_SHADER_BYTES},
|
||||
nodes::{
|
||||
drawable::{
|
||||
model::{MaterialWrapper, ModelPart},
|
||||
shaders::PANEL_SHADER_BYTES,
|
||||
},
|
||||
items::camera::TexWrapper,
|
||||
},
|
||||
};
|
||||
use mint::Vector2;
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use send_wrapper::SendWrapper;
|
||||
use smithay::{
|
||||
backend::renderer::{
|
||||
@@ -42,8 +49,8 @@ pub struct CoreSurface {
|
||||
pub dh: DisplayHandle,
|
||||
pub weak_surface: wayland_server::Weak<WlSurface>,
|
||||
mapped_data: Mutex<Option<CoreSurfaceData>>,
|
||||
sk_tex: OnceCell<SendWrapper<Mutex<Tex>>>,
|
||||
sk_mat: OnceCell<SendWrapper<Mutex<Material>>>,
|
||||
sk_tex: OnceCell<Mutex<TexWrapper>>,
|
||||
sk_mat: OnceCell<Mutex<MaterialWrapper>>,
|
||||
material_offset: Mutex<Delta<u32>>,
|
||||
on_mapped: Mutex<Box<dyn Fn() + Send + Sync>>,
|
||||
on_commit: Mutex<Box<dyn Fn(u32) + Send + Sync>>,
|
||||
@@ -93,7 +100,7 @@ impl CoreSurface {
|
||||
};
|
||||
|
||||
let sk_tex = self.sk_tex.get_or_init(|| {
|
||||
SendWrapper::new(Mutex::new(Tex::new(
|
||||
Mutex::new(TexWrapper(Tex::new(
|
||||
TexType::ImageNomips,
|
||||
TexFormat::RGBA32Linear,
|
||||
nanoid::nanoid!(),
|
||||
@@ -106,9 +113,9 @@ impl CoreSurface {
|
||||
// });
|
||||
|
||||
let mut mat = Material::new(shader, None);
|
||||
mat.diffuse_tex(sk_tex.lock().as_ref());
|
||||
mat.diffuse_tex(&sk_tex.lock().0);
|
||||
mat.transparency(Transparency::Blend);
|
||||
SendWrapper::new(Mutex::new(mat))
|
||||
Mutex::new(MaterialWrapper(mat))
|
||||
});
|
||||
|
||||
// Let smithay handle buffer management (has to be done here as RendererSurfaceStates is not thread safe)
|
||||
@@ -154,6 +161,7 @@ impl CoreSurface {
|
||||
};
|
||||
sk_tex
|
||||
.lock()
|
||||
.0
|
||||
.set_native_surface(
|
||||
smithay_tex.tex_id() as usize as *mut c_void,
|
||||
TexType::ImageNomips,
|
||||
@@ -167,7 +175,7 @@ impl CoreSurface {
|
||||
.address_mode(TexAddress::Clamp);
|
||||
|
||||
if let Some(material_offset) = self.material_offset.lock().delta() {
|
||||
sk_mat.lock().queue_offset(*material_offset as i32);
|
||||
sk_mat.lock().0.queue_offset(*material_offset as i32);
|
||||
}
|
||||
|
||||
let Some(surface_size) = renderer_surface_state.surface_size() else {
|
||||
@@ -212,7 +220,7 @@ impl CoreSurface {
|
||||
if let Some(sk_mat) = self.sk_mat.get() {
|
||||
let sk_mat = sk_mat.lock();
|
||||
for model_node in self.pending_material_applications.get_valid_contents() {
|
||||
model_node.replace_material_now(sk_mat.as_ref());
|
||||
model_node.replace_material_now(&sk_mat.0);
|
||||
}
|
||||
self.pending_material_applications.clear();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user