1use std::collections::HashMap;
2use std::vec::Vec;
3use glium::Display;
4use glium::glutin::surface::WindowSurface;
5use crate::geometry::{BoneTransforms, BoundingBox, Vertex};
6use nalgebra::{Vector3, Matrix4, Translation3, UnitQuaternion, Point3};
7use crate::{animation, debug_geo, geometry, smart_format};
8use uuid::Uuid;
9
10
11use std::fs::File;
12use std::io::BufReader;
13use glium::uniforms::UniformBuffer;
14use nalgebra_glm::normalize;
15use obj::{load_obj, Obj};
16use serde::{Deserialize, Serialize};
17use crate::animation::{AnimationState, MAX_BONES};
18use crate::logging::{EnigmaError, EnigmaMessage, EnigmaWarning};
19
20pub struct ObjectInstance {
21 pub vertex_buffers: Vec<(glium::vertex::VertexBufferAny, usize)>,
22 pub index_buffers: Vec<glium::IndexBuffer<u32>>,
23 pub instance_matrices: Vec<[[f32; 4]; 4]>,
24 pub instance_attributes: glium::VertexBuffer<geometry::InstanceAttribute>,
25}
26
27#[derive(Serialize, Deserialize, Clone)]
28pub struct ObjectSerializer {
29 pub name: String,
30 pub transform: TransformSerializer,
31 collision: bool,
32 shapes: Vec<Shape>,
33 materials: Vec<String>,
34 unique_id: String,
35 cloned_id: String,
36 animations: HashMap<String, animation::AnimationSerializer>,
37 skeleton: Option<animation::SkeletonSerializer>,
38}
39
40pub struct Object {
41 pub name: String,
42 pub transform: Transform,
43 collision: bool,
44 shapes: Vec<Shape>,
45 materials: Vec<Uuid>,
46 bounding_box: Option<geometry::BoundingBox>,
47 unique_id: Uuid,
48 cloned_id: Uuid,
49 animations: HashMap<String, animation::Animation>,
50 skeleton: Option<animation::Skeleton>,
51 current_animation: Option<AnimationState>,
52}
53
54impl Clone for Object {
55 fn clone(&self) -> Self {
56 let mut new_object = Object::new(Some(self.name.clone()));
58
59 new_object.transform.set_position(self.transform.get_position().into());
61 new_object.transform.set_rotation(self.transform.get_rotation().into());
62 new_object.transform.set_scale(self.transform.get_scale().into());
63
64 for shape in self.shapes.iter() {
66 let mut new_shape = Shape::new();
67 new_shape.vertices = shape.vertices.clone();
68 new_shape.indices = shape.indices.clone();
69 new_shape.material_index = shape.material_index;
70 new_object.add_shape(new_shape);
71 }
72
73 new_object.materials = self.materials.clone();
75
76 new_object.bounding_box = self.bounding_box.clone();
77 new_object.unique_id = Uuid::new_v4();
78 new_object.cloned_id = self.unique_id;
79 new_object.animations = self.animations.clone();
80 new_object.skeleton = self.skeleton.clone();
81 new_object
82 }
83}
84
85#[derive(Serialize, Deserialize)]
86pub struct Shape {
87 pub vertices: Vec<Vertex>,
88 pub indices: Vec<u32>,
89 pub material_index: usize,
90}
91
92impl Clone for Shape {
93 fn clone(&self) -> Self {
94 Shape {
95 vertices: self.vertices.clone(),
96 indices: self.indices.clone(),
97 material_index: self.material_index,
98 }
99 }
100}
101
102impl Shape {
103 pub fn new() -> Self {
104 Shape {
105 vertices: Vec::new(),
106 indices: Vec::new(),
107 material_index: 0,
108 }
109 }
110
111 pub fn from_vertices_indices(vertices: Vec<Vertex>, indices: Vec<u32>) -> Self {
112 Shape {
113 vertices,
114 indices,
115 material_index: 0,
116 }
117 }
118
119 pub fn default() -> Self {
120 let triangle = debug_geo::TRIANGLE;
121 let mut shape = Shape::new();
122 shape.vertices = triangle.to_vec();
123 for i in 0..triangle.iter().len() {
124 shape.indices.push(i as u32);
125 }
126 shape
127 }
128
129 pub fn get_vertex_buffer(&self, display: Display<WindowSurface>) -> glium::VertexBuffer<Vertex> {
130 glium::VertexBuffer::new(&display, &self.vertices).unwrap()
131 }
132
133 pub fn get_index_buffer(&self, display: Display<WindowSurface>) -> glium::IndexBuffer<u32> {
134 glium::IndexBuffer::new(&display, glium::index::PrimitiveType::TrianglesList, &self.indices).unwrap()
135 }
136
137 pub fn set_material_from_object_list(&mut self, material_index: usize) {
138 self.material_index = material_index;
139 }
140}
141
142impl ObjectInstance {
143 pub fn new(display: &Display<WindowSurface>) -> Self {
144 Self {
145 vertex_buffers: Vec::new(),
146 index_buffers: Vec::new(),
147 instance_matrices: Vec::new(),
148 instance_attributes: glium::vertex::VertexBuffer::dynamic(display, &Vec::new()).expect("Building ObjectInstance, Per Instance Attribute could not be created"),
149 }
150 }
151
152 pub fn set_vertex_buffers(&mut self, buffers: Vec<(glium::vertex::VertexBufferAny, usize)>) {
153 self.vertex_buffers = buffers;
154 }
155
156 pub fn set_index_buffers(&mut self, buffers: Vec<glium::IndexBuffer<u32>>) {
157 self.index_buffers = buffers;
158 }
159
160 pub fn add_instance(&mut self, instance: [[f32; 4]; 4]) {
161 self.instance_matrices.push(instance);
162 }
163}
164
165impl Object {
166 pub fn new(name: Option<String>) -> Self {
167 let uuid = Uuid::new_v4();
168 let mut object = Object {
169 name: name.unwrap_or_else(|| String::from("Object")),
170 transform: Transform::new(),
171 shapes: Vec::new(),
172 materials: Vec::new(),
173 bounding_box: None,
174 unique_id: uuid,
175 cloned_id: uuid,
176 collision: true,
177 animations: HashMap::new(),
178 skeleton: None,
179 current_animation: None,
180 };
181 object.calculate_bounding_box();
182 object
183 }
184
185 pub fn to_serializer(&self) -> ObjectSerializer {
186 let name = self.name.clone();
187 let transform = self.transform.to_serializer();
188 let mut animations = HashMap::new();
189 for (n, a) in &self.animations {
190 animations.insert(n.to_string(), a.to_serializer());
191 }
192 let shapes = self.shapes.clone();
193 let materials = self.materials.iter().map(|x| x.to_string()).collect();
194 let unique_id = self.unique_id.to_string();
195 let cloned_id = self.cloned_id.to_string();
196 ObjectSerializer {
197 name,
198 transform,
199 shapes,
200 materials,
201 unique_id,
202 cloned_id,
203 collision: self.collision,
204 animations,
205 skeleton: match &self.skeleton {
206 Some(skeleton) => Some(skeleton.to_serializer()),
207 None => None
208 },
209 }
210 }
211
212 pub fn from_serializer(serializer: ObjectSerializer) -> Self {
213 let mut object = Object::new(Some(serializer.name));
214 object.transform = Transform::from_serializer(serializer.transform);
215 object.shapes = serializer.shapes;
216 for mat in serializer.materials {
217 object.add_material(Uuid::parse_str(mat.as_str()).expect("failed to parse material uuid"));
218 }
219 object.unique_id = uuid::Uuid::parse_str(serializer.unique_id.as_str()).unwrap();
220 object.cloned_id = uuid::Uuid::parse_str(serializer.cloned_id.as_str()).unwrap();
221 object.collision = serializer.collision;
222 object.calculate_bounding_box();
223
224 let mut animations = HashMap::new();
225 for (n, s) in serializer.animations {
226 let anim = animation::Animation::from_serializer(s);
227 animations.insert(n, anim);
228 }
229 object.animations = animations;
230 object.skeleton = match serializer.skeleton {
231 Some(s) => Some(animation::Skeleton::from_serializer(s)),
232 None => None
233 };
234 object
235 }
236
237 pub fn set_collision(&mut self, collision: bool) {
238 self.collision = collision;
239 }
240
241 pub fn get_collision(&self) -> &bool {
242 &self.collision
243 }
244
245 pub fn get_unique_id(&self) -> Uuid {
246 self.unique_id
247 }
248
249 pub fn get_instance_id(&self) -> Uuid {
250 self.cloned_id
251 }
252
253 pub fn break_instance(&mut self) {
254 self.cloned_id = self.unique_id;
255 }
256
257 fn calculate_bounding_box(&mut self) -> BoundingBox {
258 let mut min_x = f32::INFINITY;
259 let mut min_y = f32::INFINITY;
260 let mut min_z = f32::INFINITY;
261 let mut max_x = f32::NEG_INFINITY;
262 let mut max_y = f32::NEG_INFINITY;
263 let mut max_z = f32::NEG_INFINITY;
264
265 for shape in self.get_shapes().iter() {
266 for vertex in shape.vertices.iter() {
267 min_x = min_x.min(vertex.position[0]);
268 min_y = min_y.min(vertex.position[1]);
269 min_z = min_z.min(vertex.position[2]);
270 max_x = max_x.max(vertex.position[0]);
271 max_y = max_y.max(vertex.position[1]);
272 max_z = max_z.max(vertex.position[2]);
273 }
274 }
275
276 let min_point = Point3::new(min_x, min_y, min_z);
277 let max_point = Point3::new(max_x, max_y, max_z);
278
279 let center = Point3::new(
280 (min_point.x + max_point.x) / 2.0,
281 (min_point.y + max_point.y) / 2.0,
282 (min_point.z + max_point.z) / 2.0,
283 );
284 self.transform.update();
285 let transformed_center = self.transform.matrix.transform_point(¢er);
286 let transformed_width = (max_x - min_x) * self.transform.get_scale().x;
287 let transformed_height = (max_y - min_y) * self.transform.get_scale().y;
288 let transformed_depth = (max_z - min_z) * self.transform.get_scale().z;
289
290 let aabb = BoundingBox {
291 center: Vector3::from([transformed_center.x, transformed_center.y, transformed_center.z]),
292 width: transformed_width,
293 height: transformed_height,
294 depth: transformed_depth,
295 };
296 self.bounding_box = Some(aabb);
297 aabb
298 }
299
300 pub fn default() -> Self {
301 let mut object = Object::new(None);
302 object.add_shape(Shape::default());
303 object
304 }
305
306 fn update_animation_internal(&mut self, delta_time: f32) {
307 if let Some(anim_state) = &mut self.current_animation {
308 if let Some(animation) = self.animations.get(&anim_state.name) {
309 anim_state.time += delta_time * anim_state.speed;
310 if anim_state.time > animation.duration {
311 if anim_state.looping {
312 anim_state.time %= animation.duration;
313 } else {
314 anim_state.time = animation.duration;
315 }
316 }
317 }
318 }
319 }
320
321 pub fn has_skeletal_animation(&self) -> bool {
322 self.skeleton.is_some() && !self.animations.is_empty()
323 }
324
325 #[allow(unreachable_code)]
326 pub fn get_bone_transform_buffer(&self, display: &Display<WindowSurface>) -> UniformBuffer<BoneTransforms> {
327 let bone_transform_data = BoneTransforms {
328 bone_transforms: [[[1.0; 4]; 4]; MAX_BONES],
329 };
330 return UniformBuffer::new(display, bone_transform_data).expect("Failed to create BoneTransform Buffer");
332
333 if let (Some(skeleton), Some(anim_state)) = (&self.skeleton, &self.current_animation) {
334 if let Some(animation) = self.animations.get(anim_state.name.as_str()) {
335 let mut global_transforms = vec![Matrix4::identity(); skeleton.bones.len()];
336
337 for (i, bone) in skeleton.bones.iter().enumerate() {
338 let local_transform = self.interpolate_keyframes(animation, i, anim_state.time);
339 let parent_transform: Matrix4<f32> = bone.parent_id
340 .map(|id| global_transforms[id])
341 .unwrap_or_else(Matrix4::identity);
342
343 global_transforms[i] = parent_transform * local_transform;
344 let final_transform: Matrix4<f32> = global_transforms[i] * bone.inverse_bind_pose;
345
346 bone_transform_data.bone_transforms[i] = final_transform.into();
347
348 EnigmaWarning::new(Some(smart_format!("Bone {}: {}", i, final_transform).as_str()), true).log();
349 }
350 }
351 }
352
353 UniformBuffer::new(display, bone_transform_data).expect("Failed to create BoneTransform Buffer")
354 }
355
356 fn interpolate_keyframes(&self, animation: &animation::Animation, bone_id: usize, time: f32) -> Matrix4<f32> {
357 if let Some(channel) = animation.channels.iter().find(|c| c.bone_id == bone_id) {
358 let mut prev_keyframe = &channel.keyframes[0];
359 let mut next_keyframe = prev_keyframe;
360
361 for keyframe in &channel.keyframes {
362 if keyframe.time > time {
363 next_keyframe = keyframe;
364 break;
365 }
366 prev_keyframe = keyframe;
367 }
368
369 let t = (time - prev_keyframe.time) / (next_keyframe.time - prev_keyframe.time);
370
371 match (&prev_keyframe.transform, &next_keyframe.transform) {
372 (animation::AnimationTransform::Translation(prev), animation::AnimationTransform::Translation(next)) => {
373 let interpolated = Vector3::new(
374 prev[0] + (next[0] - prev[0]) * t,
375 prev[1] + (next[1] - prev[1]) * t,
376 prev[2] + (next[2] - prev[2]) * t,
377 );
378 Matrix4::new_translation(&interpolated)
379 }
380 (animation::AnimationTransform::Rotation(prev), animation::AnimationTransform::Rotation(next)) => {
381 let prev_quat = UnitQuaternion::from_quaternion(nalgebra::Quaternion::new(prev[3], prev[0], prev[1], prev[2]));
382 let next_quat = UnitQuaternion::from_quaternion(nalgebra::Quaternion::new(next[3], next[0], next[1], next[2]));
383 prev_quat.slerp(&next_quat, t).to_homogeneous()
384 }
385 (animation::AnimationTransform::Scale(prev), animation::AnimationTransform::Scale(next)) => {
386 let interpolated = Vector3::new(
387 prev[0] + (next[0] - prev[0]) * t,
388 prev[1] + (next[1] - prev[1]) * t,
389 prev[2] + (next[2] - prev[2]) * t,
390 );
391 Matrix4::new_nonuniform_scaling(&interpolated)
392 }
393 _ => Matrix4::identity(),
394 }
395 } else {
396 Matrix4::identity()
397 }
398 }
399
400 pub fn play_animation(&mut self, name: &str, looping: bool) {
401 if let Some(_) = self.animations.get(name) {
402 self.current_animation = Some(AnimationState {
403 name: name.to_string(),
404 time: 0.0,
405 speed: 1.0,
406 looping,
407 });
408 }
409 }
410
411 pub fn stop_animation(&mut self) {
412 self.current_animation = None;
413 }
414
415 pub fn get_current_animation(&self) -> &Option<AnimationState> {
416 &self.current_animation
417 }
418
419 pub fn update(&mut self, delta_time: f32) {
420 self.transform.update();
421 if self.skeleton.is_some() && self.current_animation.is_some() {
422 self.update_animation_internal(delta_time);
423 }
424 }
425
426 pub fn get_closest_lights(&self, lights: &Vec<crate::light::Light>) -> Vec<crate::light::Light> {
427 let mut closest_lights = Vec::new();
428
429 for light in lights.iter() {
431 let light_pos = light.position;
432 let object_pos = self.transform.get_position();
433 let distance = (Vector3::from(light_pos) - object_pos).magnitude();
434 if closest_lights.len() < 4 {
435 closest_lights.push((light.clone(), distance));
436 } else {
437 let mut max_distance = 0.0;
438 let mut max_index = 0;
439 for (index, (_, distance)) in closest_lights.iter().enumerate() {
440 if *distance > max_distance {
441 max_distance = *distance;
442 max_index = index;
443 }
444 }
445 if distance < max_distance {
446 closest_lights[max_index] = (light.clone(), distance.clone());
447 }
448 }
449 }
450 closest_lights.iter().map(|(light, _)| light.clone()).collect()
451 }
452
453 pub fn add_shape(&mut self, shape: Shape) {
454 self.shapes.push(shape);
455 }
456
457 pub fn get_vertex_buffers(&self, display: &Display<WindowSurface>) -> Vec<(glium::vertex::VertexBufferAny, usize)> {
458 let shapes = self.get_shapes();
459 let mut buffer = Vec::new();
460 for shape in shapes.iter() {
461 let vertex: glium::vertex::VertexBufferAny = glium::VertexBuffer::new(display, &shape.vertices).unwrap().into();
462 buffer.push((vertex, shape.material_index));
463 }
464 buffer
465 }
466
467 pub fn get_index_buffers(&self, display: &Display<WindowSurface>) -> Vec<glium::IndexBuffer<u32>> {
468 let shapes = self.get_shapes();
469 let mut buffer = Vec::new();
470 for shape in shapes.iter() {
471 let index = glium::IndexBuffer::new(display, glium::index::PrimitiveType::TrianglesList, &shape.indices).unwrap();
472 buffer.push(index);
473 }
474 buffer
475 }
476 pub fn get_bounding_box(&mut self) -> BoundingBox {
477 self.calculate_bounding_box()
478 }
479
480 pub fn get_materials(&self) -> &Vec<Uuid> {
481 &self.materials
482 }
483
484 pub fn get_materials_mut(&mut self) -> &mut Vec<Uuid> {
485 &mut self.materials
486 }
487
488 pub fn add_material(&mut self, material: Uuid) {
489 self.materials.push(material);
490 }
491
492 pub fn get_shapes(&self) -> &Vec<Shape> {
493 &self.shapes
494 }
495
496 pub fn get_shapes_mut(&mut self) -> &mut Vec<Shape> {
497 &mut self.shapes
498 }
499
500 pub fn get_name(&self) -> &String {
501 &self.name
502 }
503
504 pub fn set_name(&mut self, name: String) {
505 self.name = name;
506 }
507
508 pub fn get_animations(&self) -> &HashMap<String, animation::Animation> {
509 &self.animations
510 }
511 pub fn get_animations_mut(&mut self) -> &mut HashMap<String, animation::Animation> {
512 &mut self.animations
513 }
514
515 pub fn get_skeleton(&self) -> &Option<animation::Skeleton> {
516 &self.skeleton
517 }
518
519 pub fn get_skeleton_mut(&mut self) -> &mut Option<animation::Skeleton> {
520 &mut self.skeleton
521 }
522
523 pub fn try_fix_object(&mut self) -> Result<EnigmaMessage, EnigmaError> {
524 let mut errors = EnigmaError::new(None, true);
525 if let Some(skeleton) = &mut self.skeleton {
526 match skeleton.try_fix() {
527 Ok(_) => {},
528 Err(e) => errors.merge(e),
529 }
530 }
531
532 if !errors.is_empty() {
533 Err(errors)
534 } else {
535 Ok(EnigmaMessage::new(Some(&smart_format!("Nothing to Repair on Object {:?}", self.get_name())), true))
536 }
537 }
538
539 pub fn load_from_obj(path: &str) -> Self {
540 let input = BufReader::new(File::open(path).expect("Failed to open file"));
541 let obj: Obj = load_obj(input).unwrap();
542 let mut vertices = Vec::new();
543 let mut indices = Vec::new();
544 for vert in obj.vertices.iter() {
545 let vertex = geometry::Vertex { position: vert.position, color: [1.0, 1.0, 1.0], texcoord: [0.0, 0.0], normal: vert.normal, bone_indices: [0, 0, 0, 0], bone_weights: [0.0, 0.0, 0.0, 0.0] };
546 vertices.push(vertex);
547 }
548 for index in obj.indices.iter() {
549 indices.push((*index).into());
550 }
551
552 let shape = Shape::from_vertices_indices(vertices, indices);
553 let mut object = Object::new(obj.name);
554 object.add_shape(shape);
555 object
556 }
557
558 pub fn load_from_gltf_resource(data: &[u8], rig_scale_multiplier: Option<f32>) -> Self {
559 let (gltf, buffers, images) = gltf::import_slice(data).expect("Failed to import gltf file"); let object = Object::new(Some(String::from("INTERNAL ENIGMA RESOURCE")));
561 Object::load_from_gltf_internal((gltf, buffers, images), object, rig_scale_multiplier.unwrap_or_else(|| 1.0f32))
562 }
563
564 pub fn load_from_gltf(path: &str, rig_scale_multiplier: Option<f32>) -> Self {
565 let (gltf, buffers, images) = gltf::import(path).expect("Failed to import gltf file");
566 let object = Object::new(Some(String::from(path)));
567 Object::load_from_gltf_internal((gltf, buffers, images), object, rig_scale_multiplier.unwrap_or_else(|| 1.0f32))
568 }
569
570 fn load_from_gltf_internal(content: (gltf::Document, Vec<gltf::buffer::Data>, Vec<gltf::image::Data>), mut object: Object, rig_scale_multiplier: f32) -> Self {
571 let (gltf, buffers, _images) = content;
572 for mesh in gltf.meshes() {
573 let mut vertices = Vec::new();
574 let mut indices = Vec::new();
575 for primitive in mesh.primitives() {
576 let reader = primitive.reader(|buffer| buffers.get(buffer.index()).map(|data| &data[..]));
577
578 let positions = reader.read_positions().unwrap();
579 let normals = reader.read_normals().unwrap();
580 let tex_coords = reader.read_tex_coords(0).unwrap().into_f32();
581 let prim_indices = reader.read_indices().unwrap().into_u32();
582
583 let joints = reader.read_joints(0).map(|j| j.into_u16());
585 let weights = reader.read_weights(0).map(|w| w.into_f32());
586
587 let mut flipped_tex_coords: Vec<[f32; 2]> = Vec::new();
588 for mut tex_coord in tex_coords.into_iter() {
589 tex_coord[1] = 1.0 - tex_coord[1];
590 flipped_tex_coords.push(tex_coord);
591 }
592
593 let mut joint_data = joints.map(|j| j.map(|arr| [arr[0] as u32, arr[1] as u32, arr[2] as u32, arr[3] as u32]));
594 let mut weight_data = weights;
595
596 for ((position, normal), tex_coord) in positions.zip(normals).zip(flipped_tex_coords) {
597 let bone_indices = joint_data.as_mut().and_then(|j| j.next()).unwrap_or([0; 4]);
598 let bone_weight = weight_data.as_mut().and_then(|w| w.next()).unwrap_or([0.0; 4]);
599 let vertex = Vertex {
600 position,
601 texcoord: tex_coord,
602 color: [1.0, 1.0, 1.0],
603 normal,
604 bone_indices,
605 bone_weights: bone_weight,
606 };
607 vertices.push(vertex);
608 }
609
610 indices.extend(prim_indices);
611 }
612 let shape = Shape::from_vertices_indices(vertices, indices);
613 object.add_shape(shape);
614 }
615
616 if let Some(skin) = gltf.skins().next() {
617 let skeleton = Object::load_skeleton_internal(&gltf, &skin, &buffers, rig_scale_multiplier);
618 match skeleton.validate() {
619 Err(e) => e.log(),
620 Ok(_) => ()
621 }
622 object.skeleton = Some(skeleton)
623
624 }
625 let animations = gltf.animations();
626 for (i, animation) in animations.enumerate() {
627 let loaded_anim = Object::load_animation_internal(&animation, &buffers, i, 1.);
628 object.animations.insert(loaded_anim.name.clone(), loaded_anim);
629 }
630 object
631 }
632
633 fn load_skeleton_internal(document: &gltf::Document, skin: &gltf::Skin, buffers: &[gltf::buffer::Data], multiplier: f32) -> animation::Skeleton {
634 let reader = skin.reader(|buffer| Some(&buffers[buffer.index()]));
635
636 let joints: Vec<gltf::Node> = skin.joints().collect();
638
639 let mut inverse_bind_matrices: Vec<Matrix4<f32>> = reader.read_inverse_bind_matrices()
641 .map(|iter| iter.map(Matrix4::from).collect())
642 .unwrap_or_else(|| vec![Matrix4::identity(); joints.len()]);
643
644 inverse_bind_matrices = inverse_bind_matrices.iter_mut().map(|x| *x * multiplier).collect();
646
647 let mut parent_map = HashMap::new();
649 for node in document.nodes() {
650 for child in node.children() {
651 parent_map.insert(child.index(), node.index());
652 }
653 }
654
655 let bones = joints.into_iter().enumerate().zip(inverse_bind_matrices).map(|((id, joint), ibm)| {
656 animation::Bone {
657 name: joint.name().unwrap_or("").to_string(),
658 id,
659 parent_id: parent_map.get(&joint.index()).cloned(),
660 inverse_bind_pose: ibm,
661 }
662 }).collect();
663
664 animation::Skeleton { bones }
665 }
666
667 fn load_animation_internal(anim: &gltf::Animation, buffers: &[gltf::buffer::Data], padding: usize, multiplier: f32) -> animation::Animation {
668 let mut channels = Vec::new();
669 let mut duration: f32 = 0.0;
670 let name = match anim.name() {
671 Some(n) => n.to_string(),
672 None => format!("animation_{}", padding)
673 };
674 for channel in anim.channels() {
675 let reader = channel.reader(|buffer| Some(&buffers[buffer.index()]));
676 let bone_id = channel.target().node().index();
677 let mut keyframes = Vec::new();
678 if let (Some(times), Some(outputs)) = (reader.read_inputs(), reader.read_outputs()) {
679 let times: Vec<f32> = times.collect();
680 if let Some(&channel_duration) = times.iter().max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)) {
682 duration = duration.max(channel_duration);
683 }
684 match outputs {
685 gltf::animation::util::ReadOutputs::Translations(translations) => {
686 for (i, translation) in translations.enumerate() {
687 let translation = Vector3::from(translation);
688 keyframes.push(animation::AnimationKeyframe {
689 time: times[i],
690 transform: animation::AnimationTransform::Translation((translation * multiplier).into()),
691 });
692 }
693 }
694 gltf::animation::util::ReadOutputs::Rotations(rotations) => {
695 for (i, rotation) in rotations.into_f32().enumerate() {
696 let rotation = UnitQuaternion::from_quaternion(
697 nalgebra::Quaternion::new(rotation[3], rotation[0], rotation[1], rotation[2])
698 );
699 keyframes.push(animation::AnimationKeyframe {
700 time: times[i],
701 transform: animation::AnimationTransform::Rotation([rotation[0], rotation[1], rotation[2], rotation[3]]),
702 });
703 }
704 }
705 gltf::animation::util::ReadOutputs::Scales(scales) => {
706 for (i, scale) in scales.enumerate() {
707 let scale = Vector3::from(scale);
708 keyframes.push(animation::AnimationKeyframe {
709 time: times[i],
710 transform: animation::AnimationTransform::Scale((scale * multiplier).into()),
711 });
712 }
713 }
714 gltf::animation::util::ReadOutputs::MorphTargetWeights(_) => {
715 }
718 }
719 }
720
721 if !keyframes.is_empty() {
722 channels.push(animation::AnimationChannel { bone_id, keyframes });
723 }
724 }
725
726 animation::Animation {
727 name,
728 duration,
729 channels,
730 }
731 }
732}
733
734#[derive(Serialize, Deserialize, Clone)]
735pub struct TransformSerializer {
736 position: [f32; 3],
737 rotation: [f32; 3],
738 scale: [f32; 3],
739}
740
741#[derive(Copy, Clone)]
742pub struct Transform {
743 pub position: Vector3<f32>,
744 pub rotation: Vector3<f32>,
745 pub scale: Vector3<f32>,
747 pub matrix: Matrix4<f32>,
748}
749
750impl Transform {
751 pub fn new() -> Self {
752 Transform {
753 position: Vector3::new(0.0, 0.0, 0.0),
754 rotation: Vector3::new(0.0, 0.0, 0.0),
755 scale: Vector3::new(1.0, 1.0, 1.0),
756 matrix: Matrix4::identity(),
757 }
758 }
759
760 pub fn forward(&self) -> Vector3<f32> {
761 let rotation = UnitQuaternion::from_euler_angles(self.rotation.x, self.rotation.y, self.rotation.z);
763 let forward = rotation * Vector3::new(0.0, 0.0, 1.0);
764 normalize(&forward)
765 }
766
767 pub fn left(&self) -> Vector3<f32> {
768 let rotation = UnitQuaternion::from_euler_angles(self.rotation.x, self.rotation.y, self.rotation.z);
770 let left = rotation * Vector3::new(-1.0, 0.0, 0.0);
771 normalize(&left)
772 }
773
774 pub fn up(&self) -> Vector3<f32> {
775 let rotation = UnitQuaternion::from_euler_angles(self.rotation.x, self.rotation.y, self.rotation.z);
777 let up = rotation * Vector3::new(0.0, 1.0, 0.0);
778 normalize(&up)
779 }
780
781 pub fn from_serializer(serializer: TransformSerializer) -> Self {
782 let mut t = Transform::new();
783 t.set_position(serializer.position);
784 t.set_rotation(serializer.rotation);
785 t.set_scale(serializer.scale);
786 t
787 }
788
789 pub fn to_serializer(&self) -> TransformSerializer {
790 TransformSerializer {
791 position: self.get_position().into(),
792 rotation: self.get_rotation().into(),
793 scale: self.get_scale().into(),
794 }
795 }
796
797 pub fn update(&mut self) {
798 let scale_matrix = Matrix4::new_nonuniform_scaling(&self.scale);
799 let rotation_matrix = UnitQuaternion::from_euler_angles(self.rotation.x, self.rotation.y, self.rotation.z).to_homogeneous();
800 let translation_matrix = Translation3::from(self.position).to_homogeneous();
801 self.matrix = translation_matrix * rotation_matrix * scale_matrix;
803 }
804
805
806 pub fn set_position(&mut self, position: [f32; 3]) {
807 self.position = Vector3::from(position);
808 }
809
810 pub fn get_position(&self) -> Vector3<f32> {
811 self.position.clone()
812 }
813
814 pub fn set_rotation(&mut self, rotation: [f32; 3]) {
815 let radians = rotation.iter().map(|x| x.to_radians()).collect::<Vec<f32>>();
816 self.rotation = Vector3::from([radians[0], radians[1], radians[2]]);
817 }
818
819 pub fn rotate(&mut self, rotation: [f32; 3]) {
820 let cur_r = self.get_rotation();
821 let additive_rotation = [cur_r.x + rotation[0], cur_r.y + rotation[1], cur_r.z + rotation[2]];
822 let radians = additive_rotation.iter().map(|x| x.to_radians()).collect::<Vec<f32>>();
823 self.rotation = Vector3::from([radians[0], radians[1], radians[2]]);
824 }
825
826 pub fn move_dir_array(&mut self, position: [f32; 3]) {
827 let cur_p = self.get_position();
828 let additive_position = [cur_p.x + position[0], cur_p.y + position[1], cur_p.z + position[2]];
829 self.position = Vector3::from(additive_position);
830 }
831
832 pub fn move_dir_vector(&mut self, direction: Vector3<f32>) {
833 self.position += direction;
834 }
835
836 pub fn get_rotation(&self) -> Vector3<f32> {
837 let x = self.rotation.x.to_degrees();
838 let y = self.rotation.y.to_degrees();
839 let z = self.rotation.z.to_degrees();
840 Vector3::from([x, y, z])
841 }
842
843 pub fn set_scale(&mut self, scale: [f32; 3]) {
844 self.scale = Vector3::from(scale);
845 }
846
847 pub fn get_scale(&self) -> Vector3<f32> {
848 self.scale.clone()
849 }
850
851 pub fn get_matrix(&mut self) -> [[f32; 4]; 4] {
852 self.update();
853 self.matrix.into()
854 }
855
856 pub fn get_matrix_object(&mut self) -> Matrix4<f32> {
857 self.update();
858 self.matrix
859 }
860
861 pub fn lerp(&self, other: &Self, t: f32) -> Self {
862 let position = self.get_position().lerp(&other.get_position(), t);
863 let scale = self.get_scale().lerp(&other.get_scale(), t);
864 let rotation = self.get_rotation().slerp(&other.get_rotation(), t);
865
866 let mut result = Self::new();
867 result.set_position(position.into());
868 result.set_scale(scale.into());
869 result.set_rotation(rotation.into());
870 result
871 }
872}