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 {
|
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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue