diff --git a/editor/src/import.rs b/editor/src/import.rs index 10f03ef..9f0ec89 100644 --- a/editor/src/import.rs +++ b/editor/src/import.rs @@ -36,33 +36,36 @@ pub fn load_stl(path: std::path::PathBuf) -> model::Model { } pub fn load_gltf(path: std::path::PathBuf) -> model::Model { - use gltf::*; - let name = path.file_name().map(|v| v.to_string_lossy().to_string()); - let mut file = std::fs::File::open(path).unwrap(); - let model = Gltf::from_reader(&mut file).unwrap(); + let (document, buffers, _images) = gltf::import(path).unwrap(); - GltfLoader::load(name, &model) + let buffers = buffers.into_iter().map(|v| v.to_vec()).collect(); + + let loader = GltfLoader { + name, + document, + buffers, + }; + + loader.load() } -pub struct GltfLoader<'a> { - pub model: &'a gltf::Gltf, +pub struct GltfLoader { + pub name: Option, + pub document: gltf::Document, pub buffers: Vec>, } -impl<'a> GltfLoader<'a> { - pub fn load(name: Option, model: &'a gltf::Gltf) -> model::Model { - let buffers = Self::load_buffers(model); - let mut loader = Self { model, buffers }; - +impl GltfLoader { + pub fn load(mut self) -> model::Model { let mut model = model::Model { - name, + name: self.name.clone(), objects: vec![], }; - for scene in loader.model.scenes() { + for scene in self.document.scenes() { for node in scene.nodes() { - model.objects.push(loader.load_node(node)); + model.objects.push(self.load_node(node, glam::Vec3::ONE)); } } @@ -82,8 +85,20 @@ impl<'a> GltfLoader<'a> { buffer_data } - pub fn load_node(&mut self, node: gltf::Node) -> model::Object { - let transform = model::Transform::default(); + pub fn load_node(&self, node: gltf::Node, parent_scale: glam::Vec3) -> model::Object { + let (translation, orientation, scale) = node.transform().decomposed(); + + let orientation = glam::Quat::from_array(orientation); + let rotation = orientation.to_euler(glam::EulerRot::XYZ); + + let scale: glam::Vec3 = scale.into(); + let scale = scale * parent_scale; + + let transform = model::Transform { + position: translation.into(), + rotation: rotation.into(), + scale, + }; let mut object = model::Object { name: node.name().map(str::to_string), @@ -99,13 +114,13 @@ impl<'a> GltfLoader<'a> { } for child in node.children() { - object.children.push(self.load_node(child)); + object.children.push(self.load_node(child, scale)); } object } - pub fn load_primitive_mesh(&mut self, primitive: gltf::Primitive) -> model::Mesh { + pub fn load_primitive_mesh(&self, primitive: gltf::Primitive) -> model::Mesh { use gltf::mesh::util::{ReadIndices, ReadTexCoords}; if primitive.mode() != gltf::mesh::Mode::Triangles { panic!("glTF primitive must be triangle list"); diff --git a/editor/src/model.rs b/editor/src/model.rs index 1c2992b..ca986b9 100644 --- a/editor/src/model.rs +++ b/editor/src/model.rs @@ -43,7 +43,7 @@ pub struct LoadedObject { pub struct Transform { pub position: glam::Vec3, pub rotation: glam::Vec3, // TODO support glam::Quat too - pub scale: f32, + pub scale: glam::Vec3, } impl Transform { @@ -55,7 +55,7 @@ impl Transform { self.rotation[1], self.rotation[2], ); - let scale = glam::Vec3::splat(self.scale); + let scale = self.scale; glam::Mat4::from_scale_rotation_translation(scale, rotation, translation) } } @@ -65,7 +65,7 @@ impl Default for Transform { Self { position: glam::Vec3::ZERO, rotation: glam::Vec3::ZERO, - scale: 1.0, + scale: glam::Vec3::ONE, } } } diff --git a/editor/src/world.rs b/editor/src/world.rs index f187b11..4bbf813 100644 --- a/editor/src/world.rs +++ b/editor/src/world.rs @@ -144,7 +144,7 @@ impl Object { } pub fn ui_position(&mut self, ui: &mut egui::Ui) { - let speed = 0.1 * self.transform.scale; + let speed = 0.1 * self.transform.scale.min_element(); if Self::ui_vec3(ui, speed, &mut self.transform.position) { self.dirty = true; } @@ -183,11 +183,8 @@ impl Object { } pub fn ui_scale(&mut self, ui: &mut egui::Ui) { - let scale_speed = self.transform.scale * 0.01; - let drag = egui::DragValue::new(&mut self.transform.scale) - .clamp_range(0.0..=f32::INFINITY) - .speed(scale_speed); - if ui.add(drag).changed() { + let speed = self.transform.scale.min_element() * 0.01; + if Self::ui_vec3(ui, speed, &mut self.transform.scale) { self.dirty = true; } }