Upgrade glTF loader + three-axis model scales

This commit is contained in:
mars 2022-10-22 12:11:28 -06:00
parent e238fa244d
commit e9700e65fe
3 changed files with 40 additions and 28 deletions

View File

@ -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<String>,
pub document: gltf::Document,
pub buffers: Vec<Vec<u8>>,
}
impl<'a> GltfLoader<'a> {
pub fn load(name: Option<String>, 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");

View File

@ -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,
}
}
}

View File

@ -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;
}
}