Decouple model loading from spawning

This commit is contained in:
mars 2022-06-28 22:56:12 -06:00
parent f73f9c37f8
commit a5047f5875
3 changed files with 66 additions and 34 deletions

View File

@ -113,7 +113,8 @@ impl Application {
ui::ImportKind::Gltf => import::load_gltf(path),
};
let widgets = self.render_state.load_model(&model);
let loaded = self.render_state.load_model(&model);
let widgets = self.render_state.spawn_model(&loaded);
self.objects.extend(widgets.into_iter());
},
Err(crossbeam_channel::TryRecvError::Empty) => break,

View File

@ -1,3 +1,5 @@
use cyborg::storage::mesh::MeshHandle;
pub struct Model {
pub name: Option<String>,
pub objects: Vec<Object>,
@ -19,6 +21,18 @@ pub struct BasicVertex {
pub position: glam::Vec3,
}
pub struct LoadedModel {
pub name: Option<String>,
pub objects: Vec<LoadedObject>,
}
pub struct LoadedObject {
pub name: Option<String>,
pub transform: Transform,
pub meshes: Vec<MeshHandle>,
pub children: Vec<LoadedObject>,
}
#[derive(Copy, Clone, Debug)]
pub struct Transform {
pub position: glam::Vec3,

View File

@ -166,7 +166,7 @@ impl RenderState {
output_format: wgpu::TextureFormat,
render_pass: &mut egui_wgpu_backend::RenderPass,
) -> Self {
use cyborg::scene::{DebugDrawList, DebugIndex, DebugVertex};
use cyborg::scene::{DebugDrawList, DebugVertex};
use cyborg::shader::{ShaderStore, ShaderWatcher};
let mut world = legion::World::default();
@ -282,43 +282,23 @@ impl RenderState {
.execute(&mut self.world, &mut self.resources);
}
pub fn load_model(&mut self, model: &model::Model) -> Vec<ObjectWidget> {
// TODO use model name?
let mut objects = Vec::new();
for object in model.objects.iter() {
objects.push(self.load_object(object));
pub fn load_model(&mut self, model: &model::Model) -> model::LoadedModel {
model::LoadedModel {
name: model.name.clone(),
objects: model.objects.iter().map(|o| self.load_object(o)).collect(),
}
objects
}
pub fn load_object(&mut self, object: &model::Object) -> ObjectWidget {
let transform = cyborg::scene::Transform {
transform: object.transform.to_mat4(),
};
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() {
children.push(self.load_object(child));
}
ObjectWidget {
pub fn load_object(&mut self, object: &model::Object) -> model::LoadedObject {
model::LoadedObject {
name: object.name.clone(),
transform: object.transform.clone(),
entities,
children,
dirty: false,
children_dirty: false,
meshes: object.meshes.iter().map(|m| self.load_mesh(m)).collect(),
children: object
.children
.iter()
.map(|o| self.load_object(o))
.collect(),
}
}
@ -359,4 +339,41 @@ impl RenderState {
mesh_pass.get_mesh_pool().load(mesh).unwrap()
}
pub fn spawn_model(&mut self, model: &model::LoadedModel) -> Vec<ObjectWidget> {
// TODO use model name?
let mut objects = Vec::new();
for object in model.objects.iter() {
objects.push(self.spawn_object(object));
}
objects
}
pub fn spawn_object(&mut self, object: &model::LoadedObject) -> ObjectWidget {
let transform = cyborg::scene::Transform {
transform: object.transform.to_mat4(),
};
let mut entities = Vec::new();
for mesh in object.meshes.iter() {
let mesh = cyborg::scene::Mesh { mesh: *mesh };
let entity = self.world.push((mesh, transform.clone()));
entities.push(entity);
}
let mut children = Vec::new();
for child in object.children.iter() {
children.push(self.spawn_object(child));
}
ObjectWidget {
name: object.name.clone(),
transform: object.transform.clone(),
entities,
children,
dirty: false,
children_dirty: false,
}
}
}