1use std::{collections::HashMap, ops::Range};
8
9use cgmath::{InnerSpace, SquareMatrix, Zero};
10use log::warn;
11use wgpu::{Device, Queue, util::DeviceExt};
12
13use crate::{
14 context::GPUResource, data_structures::{
15 instance::{Instance, InstanceRaw},
16 model::{self, DrawModel},
17 }, pick::PickId, render::{Instanced, Render}, resources::{animation::Keyframes, load_model_obj, pick::load_pick_model}
18};
19
20#[derive(Clone, Debug)]
22pub struct AnimationClip {
23 pub name: String,
24 pub keyframes: Keyframes,
25 pub timestamps: Vec<f32>,
26}
27
28#[derive(Clone, Debug, Default)]
29pub struct ModelAnimation {
30 pub name: String,
31 pub instances: Vec<Instance>,
32 pub timestamps: Vec<f32>,
33}
34
35#[derive(Default)]
39struct ModelState {
40 animations: Vec<ModelAnimation>,
41 trans: Vec<cgmath::Vector3<f32>>,
42 rots: Vec<cgmath::Quaternion<f32>>,
43 scals: Vec<cgmath::Vector3<f32>>,
44 timestamps: Vec<f32>,
45 current_clip: String,
46}
47impl ModelState {
48 fn reset(&mut self, clip: &AnimationClip) {
49 self.timestamps = vec![];
50 self.trans = vec![];
51 self.rots = vec![];
52 self.scals = vec![];
53 self.current_clip = clip.name.clone();
54 }
55}
56
57pub fn to_scene_node(
58 id: impl Into<PickId>,
59 node: gltf::scene::Node,
60 buf: &Vec<Vec<u8>>,
61 device: &wgpu::Device,
62 mats: &Vec<model::Material>,
63 anims: &HashMap<usize, Vec<AnimationClip>>,
64) -> Box<dyn SceneNode> {
65 let animations = match anims.get(&node.index()) {
66 Some(clips) => merge(clips.clone()),
67 None => Default::default(),
68 };
69 let id = id.into();
70 let mut scene_node: Box<dyn SceneNode> = match node.mesh() {
72 Some(mesh) => {
73 let mut meshes = Vec::new();
74 let primitives = mesh.primitives();
75
76 primitives.for_each(|primitive| {
77 let reader = primitive.reader(|buffer| Some(&buf[buffer.index()]));
78
79 let mut indices = Vec::new();
80 if let Some(indices_raw) = reader.read_indices() {
81 indices.append(&mut indices_raw.into_u32().collect::<Vec<u32>>());
82 } else {
83 if let Some(positions) = reader.read_positions() {
84 indices = (0..positions.len() as u32).collect();
85 }
86 }
87
88 let mut vertices = Vec::with_capacity(indices.len());
89 if let Some(vertex_attribute) = reader.read_positions() {
90 vertex_attribute.for_each(|vertex| {
91 vertices.push(model::ModelVertex {
92 position: vertex,
93 tex_coords: Default::default(),
94 normal: Default::default(),
95 bitangent: Default::default(),
96 tangent: Default::default(),
97 })
98 });
99 }
100 if let Some(normal_attribute) = reader.read_normals() {
101 let mut normal_index = 0;
102 normal_attribute.for_each(|normal| {
103 vertices[normal_index].normal = normal;
104
105 normal_index += 1;
106 });
107 }
108 let texcoord_set = primitive
109 .material()
110 .pbr_metallic_roughness()
111 .base_color_texture()
112 .map(|t| t.tex_coord())
113 .unwrap_or(0);
114 if let Some(tex_coord_attribute) = reader.read_tex_coords(texcoord_set).map(|v| v.into_f32()) {
115 let mut tex_coord_index = 0;
116 tex_coord_attribute.for_each(|tex_coord| {
117 vertices[tex_coord_index].tex_coords = tex_coord;
118
119 tex_coord_index += 1;
120 });
121 }
122 if let Some(tangent_attribute) = reader.read_tangents() {
123 let mut tangent_index = 0;
124 tangent_attribute.for_each(|tangent| {
125 let tangent: cgmath::Vector4<f32> = tangent.into();
127 vertices[tangent_index].tangent = tangent.truncate().into();
128 let normal: cgmath::Vector3<f32> = vertices[tangent_index].normal.into();
129 let bitangent = normal.cross(tangent.truncate()) * tangent[3];
130 vertices[tangent_index].bitangent = bitangent.into();
131
132 tangent_index += 1;
133 });
134 } else {
135 if !indices.is_empty() && !vertices.is_empty() {
136 compute_tangents(&mut vertices, &indices);
137 }
138 };
139
140 let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
141 label: Some(&format!("{:?} Vertex Buffer", mesh.name())),
142 contents: bytemuck::cast_slice(&vertices),
143 usage: wgpu::BufferUsages::VERTEX,
144 });
145
146 let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
147 label: Some(&format!("{:?} Index Buffer", mesh.name())),
148 contents: bytemuck::cast_slice(&indices),
149 usage: wgpu::BufferUsages::INDEX,
150 });
151 let mat_idx = primitive.material().index().unwrap_or(0);
152
153 meshes.push(model::Mesh {
154 name: mesh.name().unwrap_or("unknown_mesh").to_string(),
155 vertex_buffer,
156 index_buffer,
157 num_elements: indices.len() as u32,
158 material: mat_idx,
159 });
160 });
161 let model = model::Model {
166 meshes,
167 materials: mats.clone(),
168 };
169 Box::new(ModelNode::from_model(1, id, device, model, animations))
170 }
171 None => Box::new(ContainerNode::new(1, animations)),
172 };
173 let decomp_pos = node.transform().decomposed();
174 let instance = Instance {
175 position: decomp_pos.0.into(),
176 rotation: decomp_pos.1.into(),
177 scale: decomp_pos.2.into(),
178 };
179 scene_node.set_local_transform(0, instance);
180 for child in node.children() {
181 let child_node = to_scene_node(id, child, buf, device, mats, anims);
182 scene_node.add_child(child_node);
183 }
184
185 scene_node
186}
187
188fn compute_tangents(vertices: &mut Vec<model::ModelVertex>, indices: &[u32]) {
189 let mut tan1 = vec![cgmath::Vector3::zero(); vertices.len()];
192 let mut tan2 = vec![cgmath::Vector3::zero(); vertices.len()];
193
194 for c in indices.chunks(3) {
196 if c.len() < 3 {
197 break;
198 } let i1 = c[0] as usize;
201 let i2 = c[1] as usize;
202 let i3 = c[2] as usize;
203
204 let v1 = &vertices[i1];
205 let v2 = &vertices[i2];
206 let v3 = &vertices[i3];
207
208 let p1: cgmath::Vector3<f32> = v1.position.into();
209 let p2: cgmath::Vector3<f32> = v2.position.into();
210 let p3: cgmath::Vector3<f32> = v3.position.into();
211
212 let w1: cgmath::Vector2<f32> = v1.tex_coords.into();
213 let w2: cgmath::Vector2<f32> = v2.tex_coords.into();
214 let w3: cgmath::Vector2<f32> = v3.tex_coords.into();
215
216 let x1 = p2.x - p1.x;
217 let x2 = p3.x - p1.x;
218 let y1 = p2.y - p1.y;
219 let y2 = p3.y - p1.y;
220 let z1 = p2.z - p1.z;
221 let z2 = p3.z - p1.z;
222
223 let s1 = w2.x - w1.x;
224 let s2 = w3.x - w1.x;
225 let t1 = w2.y - w1.y;
226 let t2 = w3.y - w1.y;
227
228 let r_denom = s1 * t2 - s2 * t1;
230 let r = if r_denom.abs() < 1e-6 {
231 0.0
232 } else {
233 1.0 / r_denom
234 };
235
236 let sdir = cgmath::Vector3::new(
237 (t2 * x1 - t1 * x2) * r,
238 (t2 * y1 - t1 * y2) * r,
239 (t2 * z1 - t1 * z2) * r,
240 );
241
242 let tdir = cgmath::Vector3::new(
243 (s1 * x2 - s2 * x1) * r,
244 (s1 * y2 - s2 * y1) * r,
245 (s1 * z2 - s2 * z1) * r,
246 );
247
248 tan1[i1] += sdir;
250 tan1[i2] += sdir;
251 tan1[i3] += sdir;
252
253 tan2[i1] += tdir;
254 tan2[i2] += tdir;
255 tan2[i3] += tdir;
256 }
257
258 for (i, vert) in vertices.iter_mut().enumerate() {
259 let n: cgmath::Vector3<f32> = vert.normal.into();
260 let t = tan1[i];
261
262 let tangent_xyz = (t - n * n.dot(t)).normalize();
264
265 let w = if n.cross(t).dot(tan2[i]) < 0.0 {
266 -1.0
267 } else {
268 1.0
269 };
270
271 if tangent_xyz.x.is_nan() {
272 vert.tangent = [1.0, 0.0, 0.0];
273 vert.bitangent = [0.0, 1.0, 0.0];
274 } else {
275 vert.tangent = tangent_xyz.into();
276 let bitangent = n.cross(tangent_xyz) * w;
277 vert.bitangent = bitangent.into();
278 }
279 }
280}
281
282fn save_current_anim(state: &mut ModelState, clip: &AnimationClip) -> ModelAnimation {
283 let t_len = state.trans.len();
284 let r_len = state.rots.len();
285 let s_len = state.scals.len();
286 let max_len = t_len.max(r_len.max(s_len));
287 if t_len != r_len || r_len != s_len {
288 log::warn!(
289 "warning, animation track len() doesn't match and will matched with defaults. previous animation: {}, current: {}",
290 state.current_clip,
291 clip.name
292 );
293 state.trans.append(
295 &mut (t_len..max_len)
296 .into_iter()
297 .filter_map(|_| state.trans.first())
298 .cloned()
299 .collect(),
300 );
301 state.rots.append(
302 &mut (r_len..max_len)
303 .into_iter()
304 .filter_map(|_| state.rots.first())
305 .cloned()
306 .collect(),
307 );
308 state.scals.append(
309 &mut (s_len..max_len)
310 .into_iter()
311 .filter_map(|_| state.scals.first())
312 .cloned()
313 .collect(),
314 );
315 }
316 let mut instances = Vec::with_capacity(t_len);
318 for i in 0..max_len {
319 let instance = Instance {
320 position: state.trans[i],
321 rotation: state.rots[i],
322 scale: state.scals[i],
323 };
324 instances.push(instance);
325 }
326 let animation = ModelAnimation {
328 name: clip.name.clone(),
329 instances,
330 timestamps: state.timestamps.clone(),
331 };
332 animation
333}
334
335fn merge(clips: Vec<AnimationClip>) -> Vec<ModelAnimation> {
365 let mut state = ModelState {
366 current_clip: clips.first().unwrap().name.clone(),
367 ..Default::default()
368 };
369 for clip in clips.iter() {
370 if clip.name != state.current_clip {
371 let animation = save_current_anim(&mut state, clip);
372 state.animations.push(animation);
373 state.reset(clip);
374 }
375 match &clip.keyframes {
376 Keyframes::Translation(translations) => translations
377 .into_iter()
378 .for_each(|&tr| state.trans.push(tr)),
379 Keyframes::Rotation(rotations) => {
380 rotations.into_iter().for_each(|&rot| state.rots.push(rot));
381 }
382 Keyframes::Scale(scalations) => {
383 scalations.into_iter().for_each(|&sc| state.scals.push(sc));
384 }
385 Keyframes::Other => todo!(),
386 }
387 if clip.timestamps.len() > state.timestamps.len() {
389 state.timestamps = clip.timestamps.clone();
390 }
391 }
392 if let Some(clip) = clips.last() {
393 let animation = save_current_anim(&mut state, clip);
394 state.animations.push(animation);
395 state.reset(clip);
396 }
397 state.animations
398}
399
400pub trait SceneNode: Send {
401 fn get_world_transforms(&self) -> Vec<Instance>;
402
403 fn get_world_transform(&self, idx: usize) -> Option<&Instance>;
404
405 fn get_local_transform(&self, idx: usize) -> Option<&Instance>;
406
407 fn draw<'a, 'pass>(
408 &self,
409 camera_bind_group_layout: &'a wgpu::BindGroup,
410 light_bind_group: &'a wgpu::BindGroup,
411 render_pass: &'pass mut wgpu::RenderPass<'a>,
412 ) where
413 'a: 'pass;
414
415 fn to_clickable(&self, device: &wgpu::Device, id: PickId) -> Box<dyn SceneNode>;
416
417 fn get_children(&self) -> &Vec<Box<dyn SceneNode>>;
418
419 fn add_child(&mut self, child: Box<dyn SceneNode>) -> usize;
421
422 fn remove_child(&mut self, idx: usize) -> Box<dyn SceneNode>;
423
424 fn set_local_transform(&mut self, idx: usize, instance: Instance);
425
426 fn set_local_transform_all(&mut self, mutation: &mut dyn FnMut(&mut Instance));
427
428 fn get_children_mut(&mut self) -> &mut Vec<Box<dyn SceneNode>>;
429
430 fn write_to_buffers(&mut self, queue: &wgpu::Queue, device: &wgpu::Device);
431
432 fn update_world_transforms(
435 &mut self,
436 range: Range<usize>,
437 parents_world_transform: &Vec<Instance>,
438 );
439
440 fn update_world_transform_all(&mut self);
441
442 fn add_instance(&mut self, instance: Instance) -> usize;
444
445 fn add_instances(&mut self, instances: Vec<Instance>) -> usize;
447
448 fn set_instances(&mut self, instances: Vec<Instance>) -> usize;
449
450 fn remove_instance(&mut self, idx: usize) -> (Instance, Instance);
451
452 fn duplicate_instance(&mut self, i: usize) -> usize;
453
454 fn get_animation(&self) -> &Vec<ModelAnimation>;
455
456 fn get_render(&self) -> Vec<Instanced<'_>>;
457
458 fn get_render_dir(&self) -> wgpu::FrontFace {
459 wgpu::FrontFace::Ccw
460 }
461
462 fn render_inverted(&mut self);
463}
464impl dyn SceneNode {
465 pub fn transform_local(&mut self, instance: Instance) -> Instance {
466 let idx = self.add_child(Box::new(ContainerNode::from(instance)));
467 self.update_world_transforms(idx..idx + 1, &vec![Instance::new()]);
468 let child = self.remove_child(idx);
469 child.get_world_transforms()[0].clone()
470 }
471 pub fn transform_locals(&mut self, instances: Vec<Instance>) -> Vec<Instance> {
472 self.add_instances((0..instances.len()).map(|_| Instance::new()).collect());
473 let idx = self.add_child(Box::new(ContainerNode::from(instances)));
474 self.update_world_transforms(idx..idx + 1, &vec![Instance::new()]);
475 let child = self.remove_child(idx);
476 child.get_world_transforms()
477 }
478}
479
480pub fn transform_locals(parent: &Instance, children: Vec<Instance>) -> Vec<Instance> {
482 let len = children.len();
483 let parents: Vec<_> = (0..len).map(|_| parent.clone()).collect();
484 let mut scene = ContainerNode::from(parents);
485 let child = scene.add_child(Box::new(ContainerNode::from(children)));
486 scene.update_world_transforms(0..len, &(0..len).map(|_| Instance::new()).collect());
487 scene.remove_child(child).get_world_transforms()
488}
489
490pub fn transform_local(parent: &Instance, child: Instance) -> Instance {
492 parent * &child
493}
494
495#[cfg(feature = "integration-tests")]
496impl<'a, 'pass> GPUResource<'a, 'pass> for Box<dyn SceneNode> {
497 fn write_to_buffer(&mut self, queue: &wgpu::Queue, device: &wgpu::Device) {
498 (*self).write_to_buffers(queue, device);
500 }
501 fn get_render(&'a self) -> Render<'a, 'pass> {
502 Render::Defaults((**self).get_render())
503 }
504}
505
506impl<'a, 'pass, T> GPUResource<'a, 'pass> for T
507where
508 T: SceneNode,
509{
510 fn write_to_buffer(&mut self, queue: &wgpu::Queue, device: &wgpu::Device) {
511 self.write_to_buffers(queue, device);
512 }
513
514 fn get_render(&'a self) -> Render<'a, 'pass> {
515 Render::Defaults(self.get_render())
516 }
517}
518
519pub struct ContainerNode {
520 pub children: Vec<Box<dyn SceneNode>>,
521 pub instances: Vec<(Instance, Instance)>,
522 animations: Vec<ModelAnimation>,
523}
524
525impl ContainerNode {
526 pub fn new(amount: usize, animations: Vec<ModelAnimation>) -> Self {
527 let instances = (0..amount)
528 .map(|_| (Instance::default(), Instance::default()))
529 .collect();
530 let children = vec![];
531 Self {
532 instances,
533 children,
534 animations,
535 }
536 }
537}
538
539impl From<Instance> for ContainerNode {
540 fn from(value: Instance) -> Self {
541 ContainerNode {
542 children: vec![],
543 instances: vec![(value, Instance::default())],
544 animations: vec![],
545 }
546 }
547}
548
549impl From<Vec<Instance>> for ContainerNode {
550 fn from(value: Vec<Instance>) -> Self {
551 ContainerNode {
552 children: vec![],
553 instances: value
554 .iter()
555 .zip(value.iter())
556 .map(|(fst, snd)| (fst.clone(), snd.clone()))
557 .collect(),
558 animations: vec![],
559 }
560 }
561}
562
563impl SceneNode for ContainerNode {
564 fn remove_child(&mut self, idx: usize) -> Box<dyn SceneNode> {
565 self.children.remove(idx)
566 }
567
568 fn add_child(&mut self, child: Box<dyn SceneNode>) -> usize {
569 self.children.push(child);
570 return self.children.len() - 1;
571 }
572
573 fn set_local_transform(&mut self, idx: usize, instance: Instance) {
574 self.instances
575 .get_mut(idx)
576 .and_then(|(local, _)| Some(*local = instance));
577 }
578
579 fn set_local_transform_all(&mut self, mutation: &mut dyn FnMut(&mut Instance)) {
580 self.instances.iter_mut().for_each(|(local, _)| {
581 mutation(local);
582 });
583 }
584
585 fn get_world_transforms(&self) -> Vec<Instance> {
586 self.instances
587 .iter()
588 .map(|(_, world)| world)
589 .cloned()
590 .collect()
591 }
592
593 fn update_world_transforms(
598 &mut self,
599 range: Range<usize>,
600 parents_world_transform: &Vec<Instance>,
601 ) {
602 if parents_world_transform.len() > self.instances.len() {
603 warn!(
604 "You tried to transform with len {}, but there are only {} instances to transform.",
605 parents_world_transform.len(),
606 self.instances.len()
607 );
608 return;
609 }
610 if let None = self.instances.get(range.clone()) {
611 warn!(
612 "You tried to transform range {}..{}, which is out of bounds for parent len {}.",
613 range.clone().start,
614 range.end,
615 self.instances.len(),
616 );
617 return;
618 }
619 let world_transforms = self.instances[range.clone()]
620 .iter_mut()
621 .zip(parents_world_transform.into_iter())
622 .map(|((local, world), parent)| {
623 let world_transform = parent * local;
624 *world = parent * local;
625 world_transform
626 })
627 .collect::<Vec<_>>();
628 for child in self.children.iter_mut() {
629 child.update_world_transforms(range.clone(), &world_transforms);
630 }
631 }
632
633 fn get_children_mut(&mut self) -> &mut Vec<Box<dyn SceneNode>> {
634 &mut self.children
635 }
636
637 fn get_local_transform(&self, idx: usize) -> Option<&Instance> {
638 self.instances.get(idx).map(|(local, _)| local)
639 }
640
641 fn write_to_buffers(&mut self, queue: &wgpu::Queue, device: &wgpu::Device) {
642 self.get_children_mut()
643 .iter_mut()
644 .for_each(|child| child.write_to_buffers(queue, device));
645 }
646
647 fn draw<'a, 'pass>(
648 &self,
649 camera_bind_group: &'a wgpu::BindGroup,
650 light_bind_group: &'a wgpu::BindGroup,
651 render_pass: &'pass mut wgpu::RenderPass<'a>,
652 ) where
653 'a: 'pass,
654 {
655 for child in &self.children {
656 child.draw(camera_bind_group, light_bind_group, render_pass);
657 }
658 }
659
660 fn get_children(&self) -> &Vec<Box<dyn SceneNode>> {
661 &self.children
662 }
663
664 fn to_clickable(&self, device: &Device, id: PickId) -> Box<dyn SceneNode> {
665 let children = self
666 .children
667 .iter()
668 .map(|child| child.to_clickable(device, id))
669 .collect();
670
671 Box::new(Self {
672 children,
673 instances: self.instances.clone(),
674 animations: Vec::new(),
675 })
676 }
677
678 fn add_instance(&mut self, instance: Instance) -> usize {
679 self.instances.push((instance.clone(), instance));
680 for child in &mut self.children {
681 child.add_instance(Instance::default());
682 }
683 self.instances.len() - 1
684 }
685
686 fn update_world_transform_all(&mut self) {
687 let range = 0..self.instances.len();
688 let default_instances = range.clone().map(|_| Instance::default()).collect();
689 self.update_world_transforms(range, &default_instances);
690 }
691
692 fn duplicate_instance(&mut self, i: usize) -> usize {
698 self.instances
699 .push((self.instances[i].clone().0, self.instances[i].clone().1));
700 for child in &mut self.children {
701 child.duplicate_instance(i);
702 }
703 self.instances.len()
704 }
705
706 fn get_animation(&self) -> &Vec<ModelAnimation> {
707 &self.animations
708 }
709
710 fn get_render(&self) -> Vec<Instanced<'_>> {
711 self.children
712 .iter()
713 .flat_map(|child| (**child).get_render())
714 .collect()
715 }
716
717 fn remove_instance(&mut self, idx: usize) -> (Instance, Instance) {
718 self.children.iter_mut().for_each(|c| {
719 c.remove_instance(idx);
720 });
721 self.instances.remove(idx)
722 }
723
724 fn add_instances(&mut self, instances: Vec<Instance>) -> usize {
725 let cloned = instances.clone();
726 let len = instances.len();
727 let mut instances = instances.into_iter().zip(cloned).collect();
728 self.instances.append(&mut instances);
729 for child in &mut self.children {
730 child.add_instances((0..len).map(|_| Instance::default()).collect());
731 }
732 self.instances.len() - 1
733 }
734
735 fn get_world_transform(&self, idx: usize) -> Option<&Instance> {
736 self.instances.get(idx).map(|(_, world)| world)
737 }
738
739 fn set_instances(&mut self, instances: Vec<Instance>) -> usize {
740 let len = instances.len();
741 self.instances = instances.to_vec().into_iter().zip(instances).collect();
742 for child in &mut self.children {
743 child.set_instances((0..len).map(|_| Instance::default()).collect());
744 }
745 self.instances.len() - 1
746 }
747
748 fn render_inverted(&mut self) {}
749}
750
751pub struct ModelNode {
752 children: Vec<Box<dyn SceneNode>>,
753 front_face: wgpu::FrontFace,
754 instance_buffer: wgpu::Buffer,
755 instances: Vec<(Instance, Instance)>,
756 animations: Vec<ModelAnimation>,
757 buffer_size_needs_change: bool,
758 model: model::Model,
759 id: PickId,
760}
761
762impl ModelNode {
763 pub async fn new(
764 amount: usize,
765 id: impl Into<PickId>,
766 device: &Device,
767 queue: &Queue,
768 obj_file: &str,
769 ) -> Self {
770 let obj_model = load_model_obj(obj_file, &device, &queue).await;
771 if let Err(e) = obj_model {
772 panic!("Error failed to load model: {}, at {}", e, obj_file);
773 }
774 let obj_model = obj_model.unwrap();
775
776 Self::from_model(amount, id, device, obj_model, Vec::new())
777 }
778
779 pub fn from_model(
780 amount: usize,
781 id: impl Into<PickId>,
782 device: &Device,
783 obj_model: model::Model,
784 animations: Vec<ModelAnimation>,
785 ) -> Self {
786 let instances = (0..amount)
787 .map(|_| (Instance::default(), Instance::default()))
788 .collect::<Vec<_>>();
789
790 let instance_data = instances
791 .iter()
792 .map(|(_, world)| world)
793 .map(Instance::to_raw)
794 .collect::<Vec<_>>();
795
796 let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
797 label: Some("Instance Buffer"),
798 contents: bytemuck::cast_slice(&instance_data),
799 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
800 });
801
802 let size_changed = false;
803 let direction = wgpu::FrontFace::Ccw;
804
805 Self {
806 children: vec![],
807 front_face: direction,
808 instance_buffer,
809 instances,
810 model: obj_model,
811 buffer_size_needs_change: size_changed,
812 animations,
813 id: id.into(),
814 }
815 }
816}
817
818impl SceneNode for ModelNode {
819 fn add_child(&mut self, child: Box<dyn SceneNode>) -> usize {
820 self.children.push(child);
821 self.children.len() - 1
822 }
823
824 fn set_local_transform(&mut self, idx: usize, instance: Instance) {
825 self.instances
826 .get_mut(idx)
827 .and_then(|(local, _)| Some(*local = instance));
828 }
829
830 fn set_local_transform_all(&mut self, mutation: &mut dyn FnMut(&mut Instance)) {
831 self.instances
832 .iter_mut()
833 .for_each(|(local, _)| mutation(local));
834 }
835
836 fn get_world_transforms(&self) -> Vec<Instance> {
837 self.instances
838 .iter()
839 .map(|(_, world)| world)
840 .cloned()
841 .collect()
842 }
843
844 fn update_world_transforms(
849 &mut self,
850 range: Range<usize>,
851 parents_world_transform: &Vec<Instance>,
852 ) {
853 if parents_world_transform.len() > self.instances.len() {
854 warn!(
855 "You tried to transform with len {}, but there are only {} instances to transform.",
856 parents_world_transform.len(),
857 self.instances.len()
858 );
859 return;
860 }
861 if let None = self.instances.get(range.clone()) {
862 warn!(
863 "you tried to transform range {}..{}, which is out of bounds for parent len {}.",
864 range.clone().start,
865 range.end,
866 self.instances.len(),
867 );
868 return;
869 }
870 let world_transforms = self.instances[range.clone()]
871 .iter_mut()
872 .zip(parents_world_transform.into_iter())
873 .map(|((local, world), parent)| {
874 let world_transform = parent * local;
875 *world = parent * local;
876 world_transform
877 })
878 .collect::<Vec<_>>();
879 for child in self.children.iter_mut() {
880 child.update_world_transforms(range.clone(), &world_transforms);
881 }
882 }
883
884 fn get_children_mut(&mut self) -> &mut Vec<Box<dyn SceneNode>> {
885 &mut self.children
886 }
887
888 fn get_local_transform(&self, idx: usize) -> Option<&Instance> {
889 self.instances.get(idx).map(|(local, _)| local)
890 }
891
892 fn write_to_buffers(&mut self, queue: &wgpu::Queue, device: &wgpu::Device) {
893 if let Some((_, world)) = self.instances.first() {
895 let det = world.to_matrix().determinant().signum();
896 if det < 0.0 {
897 self.front_face = wgpu::FrontFace::Cw;
898 } else {
899 self.front_face = wgpu::FrontFace::Ccw;
900 }
901 }
902 let raw_instances: Vec<InstanceRaw> = self
903 .instances
904 .iter()
905 .map(|(_, world)| world.to_raw())
906 .collect();
907 if self.buffer_size_needs_change {
908 self.instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
909 label: Some("Instance Buffer"),
910 contents: bytemuck::cast_slice(&raw_instances),
911 usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
912 });
913 self.buffer_size_needs_change = false;
914 } else {
915 queue.write_buffer(
916 &self.instance_buffer,
917 0,
918 bytemuck::cast_slice(&raw_instances),
919 );
920 }
921 self.get_children_mut()
922 .iter_mut()
923 .for_each(|child| child.write_to_buffers(queue, device));
924 }
925
926 fn draw<'a, 'b>(
927 &self,
928 camera_bind_group: &'a wgpu::BindGroup,
929 light_bind_group: &'a wgpu::BindGroup,
930 render_pass: &'b mut wgpu::RenderPass<'a>,
931 ) where
932 'a: 'b,
933 {
934 let instances = self.get_world_transforms();
935 if !instances.is_empty() {
936 render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
937 render_pass.draw_model_instanced(
938 &self.model,
939 0..instances.len() as u32,
940 &camera_bind_group,
941 &light_bind_group,
942 );
943 }
944 for child in &self.children {
945 child.draw(camera_bind_group, light_bind_group, render_pass);
946 }
947 }
948
949 fn get_children(&self) -> &Vec<Box<dyn SceneNode>> {
950 &self.children
951 }
952
953 fn to_clickable(&self, device: &wgpu::Device, id: PickId) -> Box<dyn SceneNode> {
954 let obj_model = load_pick_model(&device, id, self.model.meshes.clone()).unwrap();
955
956 let children = self
957 .children
958 .iter()
959 .map(|child| child.to_clickable(device, id))
960 .collect();
961
962 Box::new(Self {
963 children,
964 front_face: self.front_face,
965 instance_buffer: self.instance_buffer.clone(),
966 instances: self.instances.clone(),
967 buffer_size_needs_change: false,
968 model: obj_model,
969 animations: Vec::new(),
970 id: id.into(),
971 })
972 }
973
974 fn add_instance(&mut self, instance: Instance) -> usize {
975 self.instances.push((instance.clone(), instance));
976 for child in &mut self.children {
977 child.add_instance(Instance::default());
978 }
979 self.buffer_size_needs_change = true;
980 self.instances.len() - 1
981 }
982
983 fn update_world_transform_all(&mut self) {
984 let range = 0..self.instances.len();
985 let default_instances = range.clone().map(|_| Instance::default()).collect();
986 self.update_world_transforms(range, &default_instances);
987 }
988
989 fn duplicate_instance(&mut self, i: usize) -> usize {
990 self.instances
991 .push((self.instances[i].clone().0, self.instances[i].clone().1));
992 for child in &mut self.children {
993 child.duplicate_instance(i);
994 }
995 self.buffer_size_needs_change = true;
996 self.instances.len() - 1
997 }
998
999 fn get_animation(&self) -> &Vec<ModelAnimation> {
1000 &self.animations
1001 }
1002
1003 fn get_render(&self) -> Vec<Instanced<'_>> {
1004 self.children
1005 .iter()
1006 .flat_map(|child| (**child).get_render())
1007 .chain([Instanced {
1008 instance: &self.instance_buffer,
1009 model: &self.model,
1010 amount: self.instances.len(),
1011 front_face: self.front_face,
1012 id: self.id,
1013 }])
1014 .collect()
1015 }
1016
1017 fn remove_instance(&mut self, idx: usize) -> (Instance, Instance) {
1018 self.children.iter_mut().for_each(|c| {
1019 c.remove_instance(idx);
1020 });
1021 self.buffer_size_needs_change = true;
1022 self.instances.remove(idx)
1023 }
1024
1025 fn add_instances(&mut self, instances: Vec<Instance>) -> usize {
1026 let cloned = instances.clone();
1027 let len = instances.len();
1028 let mut instances = instances.into_iter().zip(cloned).collect();
1029 self.instances.append(&mut instances);
1030 for child in &mut self.children {
1031 child.add_instances((0..len).map(|_| Instance::default()).collect());
1032 }
1033 self.buffer_size_needs_change = true;
1034 self.instances.len() - 1
1035 }
1036
1037 fn get_world_transform(&self, idx: usize) -> Option<&Instance> {
1038 self.instances.get(idx).map(|(_, world)| world)
1039 }
1040
1041 fn remove_child(&mut self, idx: usize) -> Box<dyn SceneNode> {
1042 self.children.remove(idx)
1043 }
1044
1045 fn set_instances(&mut self, instances: Vec<Instance>) -> usize {
1046 let len = instances.len();
1047 self.instances = instances.to_vec().into_iter().zip(instances).collect();
1048 for child in &mut self.children {
1049 child.set_instances((0..len).map(|_| Instance::default()).collect());
1050 }
1051 self.buffer_size_needs_change = true;
1052 self.instances.len() - 1
1053 }
1054
1055 fn render_inverted(&mut self) {
1056 self.front_face = wgpu::FrontFace::Cw;
1057 }
1058}
1059
1060pub async fn mk_flat_scene_graph(
1061 amount: usize,
1062 id: impl Into<PickId>,
1063 models: Vec<&'static str>,
1064 device: &wgpu::Device,
1065 queue: &wgpu::Queue,
1066) -> anyhow::Result<Box<dyn SceneNode + Send>> {
1067 let mut parent: Box<dyn SceneNode> = Box::new(ContainerNode::new(amount, Vec::new()));
1068 let id = id.into();
1069 futures::future::join_all(
1070 models
1071 .into_iter()
1072 .map(|obj_file| ModelNode::new(amount, id, device, queue, obj_file)),
1073 )
1074 .await
1075 .into_iter()
1076 .map(Box::new)
1077 .for_each(|boxed_model_node| {
1078 parent.add_child(boxed_model_node);
1079 });
1080 Ok(parent)
1081}
1082
1083#[cfg(test)]
1084mod tests {
1085 use super::*;
1086
1087 #[test]
1088 fn preserves_number_of_children() {
1089 let parent = Instance::default();
1090 let children = vec![
1091 Instance::default(),
1092 Instance::default(),
1093 Instance::default(),
1094 ];
1095
1096 let result = transform_locals(&parent, children.clone());
1097
1098 assert_eq!(result.len(), children.len());
1099 }
1100
1101 #[test]
1102 fn identity_parent_does_not_change_children() {
1103 let parent = Instance::default();
1104 let children = vec![
1105 Instance::from(cgmath::Vector3::from([1.0, 0.0, 0.0])),
1106 Instance::from(cgmath::Vector3::from([0.0, 2.0, 0.0])),
1107 ];
1108
1109 let result = transform_locals(&parent, children.clone());
1110
1111 for (a, b) in result.iter().zip(children.iter()) {
1112 assert_eq!(a.position, b.position);
1113 assert_eq!(a.scale, b.scale);
1114 assert_eq!(a.rotation, b.rotation);
1115 }
1116 }
1117
1118 #[test]
1119 fn existing_children_unchanged() {
1120 let parent = Instance::default();
1121 let children = vec![
1122 Instance::from(cgmath::Vector3::from([1.0, 0.0, 0.0])),
1123 Instance::from(cgmath::Vector3::from([0.0, 2.0, 0.0])),
1124 ];
1125
1126 let result = transform_locals(&parent, children.clone());
1127
1128 for (a, b) in result.iter().zip(children.iter()) {
1129 assert_eq!(a.position, b.position);
1130 assert_eq!(a.scale, b.scale);
1131 assert_eq!(a.rotation, b.rotation);
1132 }
1133 }
1134
1135 #[test]
1136 fn parent_translation_is_removed() {
1137 let parent = Instance::from(cgmath::Vector3::from([10.0, 0.0, 0.0]));
1138
1139 let children = vec![
1140 Instance::from(cgmath::Vector3::from([1.0, 0.0, 0.0])),
1141 Instance::from(cgmath::Vector3::from([2.0, 0.0, 0.0])),
1142 ];
1143
1144 let result = transform_locals(&parent, children);
1145
1146 let expected = vec![
1147 Instance::from(cgmath::Vector3::from([11.0, 0.0, 0.0])),
1148 Instance::from(cgmath::Vector3::from([12.0, 0.0, 0.0])),
1149 ];
1150
1151 for (a, b) in result.iter().zip(expected.iter()) {
1152 assert_eq!(a.position, b.position);
1153 assert_eq!(a.scale, b.scale);
1154 assert_eq!(a.rotation, b.rotation);
1155 }
1156 }
1157
1158 #[test]
1159 fn empty_children_returns_empty() {
1160 let parent = Instance::default();
1161 let children = Vec::new();
1162
1163 let result = transform_locals(&parent, children);
1164
1165 assert!(result.is_empty());
1166 }
1167}