Multi-mesh objects + full scene tree
This commit is contained in:
parent
3437d4d40f
commit
45cd80d239
|
@ -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() {
|
||||
|
|
|
@ -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::<cyborg::scene::Transform>()
|
||||
.unwrap()
|
||||
.transform = transform;
|
||||
for entity in object.entities.iter() {
|
||||
self.render_state
|
||||
.world
|
||||
.entry_mut(*entity)
|
||||
.unwrap()
|
||||
.get_component_mut::<cyborg::scene::Transform>()
|
||||
.unwrap()
|
||||
.transform = transform;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ pub struct Model {
|
|||
pub struct Object {
|
||||
pub name: Option<String>,
|
||||
pub transform: Transform,
|
||||
pub mesh: Option<Mesh>,
|
||||
pub meshes: Vec<Mesh>,
|
||||
pub children: Vec<Object>,
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<String>,
|
||||
pub transform: crate::model::Transform,
|
||||
pub entity: legion::Entity,
|
||||
pub entities: Vec<legion::Entity>,
|
||||
pub children: Vec<ObjectWidget>,
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue