1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::slice::Iter;
use super::Mesh;
use crate::math::Matrix4;
use crate::pipeline::Material;
use crate::resources::Handle;
pub struct Model {
pub nodes: Vec<ModelNode>,
}
pub struct ModelNode {
pub meshes: Vec<Handle<Mesh>>,
pub materials: Vec<Handle<Material>>,
pub matrix: Matrix4,
pub children: Vec<Self>,
}
struct ChildIter<'a> {
stack: Vec<Iter<'a, ModelNode>>,
}
impl Model {
pub fn meshes(&self) -> impl Iterator<Item = &Handle<Mesh>> {
self.nodes.iter().map(|node| node.meshes()).flatten()
}
pub fn materials(&self) -> impl Iterator<Item = &Handle<Material>> {
self.nodes.iter().map(|node| node.materials()).flatten()
}
}
impl ModelNode {
pub(crate) fn orders(&self) -> impl Iterator<Item = (&Handle<Mesh>, &Handle<Material>)> {
self.meshes.iter().zip(self.materials.iter())
}
fn meshes(&self) -> impl Iterator<Item = &Handle<Mesh>> {
self.meshes
.iter()
.chain(self.child_iter().map(|node| node.meshes.iter()).flatten())
}
fn materials(&self) -> impl Iterator<Item = &Handle<Material>> {
self.materials.iter().chain(
self.child_iter()
.map(|node| node.materials.iter())
.flatten(),
)
}
fn child_iter(&self) -> ChildIter<'_> {
ChildIter {
stack: vec![self.children.iter()],
}
}
}
impl<'a> Iterator for ChildIter<'a> {
type Item = &'a ModelNode;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(mut top_iter) = self.stack.pop() {
if let Some(node) = top_iter.next() {
self.stack.push(top_iter);
self.stack.push(node.children.iter());
return Some(&node);
}
} else {
return None;
}
}
}
}