Multi-mesh objects + full scene tree

This commit is contained in:
mars 2022-05-30 00:22:49 -06:00
parent 3437d4d40f
commit 45cd80d239
5 changed files with 34 additions and 30 deletions

View File

@ -29,7 +29,7 @@ pub fn load_stl(path: std::path::PathBuf) -> model::Model {
objects: vec![model::Object { objects: vec![model::Object {
name, name,
transform: Default::default(), transform: Default::default(),
mesh: Some(model::Mesh { vertices, indices }), meshes: vec![model::Mesh { vertices, indices }],
children: vec![], children: vec![],
}], }],
} }
@ -88,14 +88,14 @@ impl<'a> GltfLoader<'a> {
let mut object = model::Object { let mut object = model::Object {
name: node.name().map(str::to_string), name: node.name().map(str::to_string),
transform, transform,
mesh: None, meshes: vec![],
children: vec![], children: vec![],
}; };
if let Some(mesh) = node.mesh() { if let Some(mesh) = node.mesh() {
assert_eq!(1, mesh.primitives().len()); for primitive in mesh.primitives() {
let primitive = mesh.primitives().next().unwrap(); object.meshes.push(self.load_primitive_mesh(primitive));
object.mesh = Some(self.load_primitive_mesh(primitive)); }
} }
for child in node.children() { for child in node.children() {

View File

@ -126,13 +126,15 @@ impl Application {
for object in self.objects.iter_mut() { for object in self.objects.iter_mut() {
object.flush_dirty(|object| { object.flush_dirty(|object| {
let transform = object.transform.to_mat4(); let transform = object.transform.to_mat4();
self.render_state for entity in object.entities.iter() {
.world self.render_state
.entry_mut(object.entity) .world
.unwrap() .entry_mut(*entity)
.get_component_mut::<cyborg::scene::Transform>() .unwrap()
.unwrap() .get_component_mut::<cyborg::scene::Transform>()
.transform = transform; .unwrap()
.transform = transform;
}
}); });
} }
} }

View File

@ -6,7 +6,7 @@ pub struct Model {
pub struct Object { pub struct Object {
pub name: Option<String>, pub name: Option<String>,
pub transform: Transform, pub transform: Transform,
pub mesh: Option<Mesh>, pub meshes: Vec<Mesh>,
pub children: Vec<Object>, pub children: Vec<Object>,
} }

View File

@ -272,19 +272,19 @@ impl RenderState {
} }
pub fn load_object(&mut self, object: &model::Object) -> ObjectWidget { 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 { let transform = cyborg::scene::Transform {
transform: object.transform.to_mat4(), transform: object.transform.to_mat4(),
}; };
let entity = if let Some(mesh) = mesh { let mut entities = Vec::new();
self.world.push((mesh, transform)) for mesh in object.meshes.iter() {
} else { let mesh = cyborg::scene::Mesh {
self.world.push((transform, ())) mesh: self.load_mesh(mesh),
}; };
let entity = self.world.push((mesh, transform.clone()));
entities.push(entity);
}
let mut children = Vec::new(); let mut children = Vec::new();
for child in object.children.iter() { for child in object.children.iter() {
@ -294,7 +294,7 @@ impl RenderState {
ObjectWidget { ObjectWidget {
name: object.name.clone(), name: object.name.clone(),
transform: object.transform.clone(), transform: object.transform.clone(),
entity, entities,
children, children,
dirty: false, dirty: false,
children_dirty: false, children_dirty: false,

View File

@ -197,9 +197,11 @@ impl UserInterface {
egui::SidePanel::left("objects_panel") egui::SidePanel::left("objects_panel")
.resizable(true) .resizable(true)
.show(ctx, |ui| { .show(ctx, |ui| {
for (index, object) in objects.iter_mut().enumerate() { egui::ScrollArea::vertical().show(ui, |ui| {
object.ui(index, ui); for (index, object) in objects.iter_mut().enumerate() {
} object.ui(index, ui);
}
});
}); });
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
@ -220,7 +222,7 @@ impl UserInterface {
let extensions: &[&str] = match kind { let extensions: &[&str] = match kind {
ImportKind::Stl => &["stl"], ImportKind::Stl => &["stl"],
ImportKind::Gltf => &["gltf", "glb"], ImportKind::Gltf => &["gltf", "glb", "vrm"],
}; };
let file_sender = self.file_sender.to_owned(); let file_sender = self.file_sender.to_owned();
@ -319,7 +321,7 @@ impl egui::Widget for &mut ViewportWidget {
pub struct ObjectWidget { pub struct ObjectWidget {
pub name: Option<String>, pub name: Option<String>,
pub transform: crate::model::Transform, pub transform: crate::model::Transform,
pub entity: legion::Entity, pub entities: Vec<legion::Entity>,
pub children: Vec<ObjectWidget>, pub children: Vec<ObjectWidget>,
pub dirty: bool, pub dirty: bool,
pub children_dirty: bool, pub children_dirty: bool,
@ -335,7 +337,7 @@ impl ObjectWidget {
for (index, child) in self.children.iter_mut().enumerate() { for (index, child) in self.children.iter_mut().enumerate() {
child.ui(index, ui); child.ui(index, ui);
if child.dirty { if child.dirty || child.children_dirty {
self.children_dirty = true; self.children_dirty = true;
} }
} }
@ -412,7 +414,7 @@ impl ObjectWidget {
pub fn flush_dirty(&mut self, mut f: impl FnMut(&mut Self)) { pub fn flush_dirty(&mut self, mut f: impl FnMut(&mut Self)) {
let mut stack = vec![self]; let mut stack = vec![self];
if let Some(parent) = stack.pop() { while let Some(parent) = stack.pop() {
if parent.dirty { if parent.dirty {
parent.dirty = false; parent.dirty = false;
f(parent); f(parent);