From 45cd80d2399ae11788f577573493b321136c75df Mon Sep 17 00:00:00 2001 From: mars Date: Mon, 30 May 2022 00:22:49 -0600 Subject: [PATCH] Multi-mesh objects + full scene tree --- editor/src/import.rs | 10 +++++----- editor/src/main.rs | 16 +++++++++------- editor/src/model.rs | 2 +- editor/src/render.rs | 20 ++++++++++---------- editor/src/ui.rs | 16 +++++++++------- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/editor/src/import.rs b/editor/src/import.rs index 0749908..10f03ef 100644 --- a/editor/src/import.rs +++ b/editor/src/import.rs @@ -29,7 +29,7 @@ pub fn load_stl(path: std::path::PathBuf) -> model::Model { objects: vec![model::Object { name, transform: Default::default(), - mesh: Some(model::Mesh { vertices, indices }), + meshes: vec![model::Mesh { vertices, indices }], children: vec![], }], } @@ -88,14 +88,14 @@ impl<'a> GltfLoader<'a> { let mut object = model::Object { name: node.name().map(str::to_string), transform, - mesh: None, + meshes: vec![], children: vec![], }; if let Some(mesh) = node.mesh() { - assert_eq!(1, mesh.primitives().len()); - let primitive = mesh.primitives().next().unwrap(); - object.mesh = Some(self.load_primitive_mesh(primitive)); + for primitive in mesh.primitives() { + object.meshes.push(self.load_primitive_mesh(primitive)); + } } for child in node.children() { diff --git a/editor/src/main.rs b/editor/src/main.rs index eb219b7..1988f7c 100644 --- a/editor/src/main.rs +++ b/editor/src/main.rs @@ -126,13 +126,15 @@ impl Application { for object in self.objects.iter_mut() { object.flush_dirty(|object| { let transform = object.transform.to_mat4(); - self.render_state - .world - .entry_mut(object.entity) - .unwrap() - .get_component_mut::() - .unwrap() - .transform = transform; + for entity in object.entities.iter() { + self.render_state + .world + .entry_mut(*entity) + .unwrap() + .get_component_mut::() + .unwrap() + .transform = transform; + } }); } } diff --git a/editor/src/model.rs b/editor/src/model.rs index d019292..0c8018f 100644 --- a/editor/src/model.rs +++ b/editor/src/model.rs @@ -6,7 +6,7 @@ pub struct Model { pub struct Object { pub name: Option, pub transform: Transform, - pub mesh: Option, + pub meshes: Vec, pub children: Vec, } diff --git a/editor/src/render.rs b/editor/src/render.rs index ce2639d..3ce2aec 100644 --- a/editor/src/render.rs +++ b/editor/src/render.rs @@ -272,19 +272,19 @@ impl RenderState { } pub fn load_object(&mut self, object: &model::Object) -> ObjectWidget { - let mesh = object.mesh.as_ref().map(|mesh| cyborg::scene::Mesh { - mesh: self.load_mesh(mesh), - }); - let transform = cyborg::scene::Transform { transform: object.transform.to_mat4(), }; - let entity = if let Some(mesh) = mesh { - self.world.push((mesh, transform)) - } else { - self.world.push((transform, ())) - }; + let mut entities = Vec::new(); + for mesh in object.meshes.iter() { + let mesh = cyborg::scene::Mesh { + mesh: self.load_mesh(mesh), + }; + + let entity = self.world.push((mesh, transform.clone())); + entities.push(entity); + } let mut children = Vec::new(); for child in object.children.iter() { @@ -294,7 +294,7 @@ impl RenderState { ObjectWidget { name: object.name.clone(), transform: object.transform.clone(), - entity, + entities, children, dirty: false, children_dirty: false, diff --git a/editor/src/ui.rs b/editor/src/ui.rs index 6099518..56aaf3f 100644 --- a/editor/src/ui.rs +++ b/editor/src/ui.rs @@ -197,9 +197,11 @@ impl UserInterface { egui::SidePanel::left("objects_panel") .resizable(true) .show(ctx, |ui| { - for (index, object) in objects.iter_mut().enumerate() { - object.ui(index, ui); - } + egui::ScrollArea::vertical().show(ui, |ui| { + for (index, object) in objects.iter_mut().enumerate() { + object.ui(index, ui); + } + }); }); egui::CentralPanel::default().show(ctx, |ui| { @@ -220,7 +222,7 @@ impl UserInterface { let extensions: &[&str] = match kind { ImportKind::Stl => &["stl"], - ImportKind::Gltf => &["gltf", "glb"], + ImportKind::Gltf => &["gltf", "glb", "vrm"], }; let file_sender = self.file_sender.to_owned(); @@ -319,7 +321,7 @@ impl egui::Widget for &mut ViewportWidget { pub struct ObjectWidget { pub name: Option, pub transform: crate::model::Transform, - pub entity: legion::Entity, + pub entities: Vec, pub children: Vec, pub dirty: bool, pub children_dirty: bool, @@ -335,7 +337,7 @@ impl ObjectWidget { for (index, child) in self.children.iter_mut().enumerate() { child.ui(index, ui); - if child.dirty { + if child.dirty || child.children_dirty { self.children_dirty = true; } } @@ -412,7 +414,7 @@ impl ObjectWidget { pub fn flush_dirty(&mut self, mut f: impl FnMut(&mut Self)) { let mut stack = vec![self]; - if let Some(parent) = stack.pop() { + while let Some(parent) = stack.pop() { if parent.dirty { parent.dirty = false; f(parent);