assimp/scene/
mesh.rs

1use ffi::{AiMesh, AiVector3D, AiBone, AiVertexWeight, AiColor4D};
2
3use math::vector3::{Vector3D, Vector3DIter};
4use math::color4::{Color4D, Color4DIter};
5use super::face::{Face, FaceIter};
6
7use math::Matrix4x4;
8
9define_type_and_iterator_indirect! {
10    /// Mesh type (incomplete)
11    struct Mesh(&AiMesh)
12    /// Mesh iterator type.
13    struct MeshIter
14}
15
16define_type_and_iterator_indirect! {
17    /// Bone type
18    struct Bone(&AiBone)
19    /// Bone iterator type.
20    struct BoneIter
21}
22
23define_type_and_iterator_indirect! {
24    /// Vertex weight type
25    struct VertexWeight(&AiVertexWeight)
26    /// Vertex weight iterator type.
27    struct VertexWeightIter
28}
29
30impl<'a> Mesh<'a> {
31    // TODO return as PrimitiveType enum
32    pub fn primitive_types(&self) -> u32 {
33        self.primitive_types
34    }
35
36    pub fn num_vertices(&self) -> u32 {
37        self.num_vertices
38    }
39
40    pub fn vertex_iter(&self) -> Vector3DIter {
41        Vector3DIter::new(self.vertices,
42                          self.num_vertices as usize)
43    }
44
45    pub fn get_vertex(&self, id: u32) -> Option<Vector3D> {
46        self.vertex_data(self.vertices, id)
47    }
48
49    pub fn normal_iter(&self) -> Vector3DIter {
50        Vector3DIter::new(self.normals,
51                          self.num_vertices as usize)
52    }
53
54    pub fn get_normal(&self, id: u32) -> Option<Vector3D> {
55        self.vertex_data(self.normals, id)
56    }
57
58    pub fn tangent_iter(&self) -> Vector3DIter {
59        Vector3DIter::new(self.tangents,
60                          self.num_vertices as usize)
61    }
62
63    pub fn get_tangent(&self, id: u32) -> Option<Vector3D> {
64        self.vertex_data(self.tangents, id)
65    }
66
67    pub fn bitangent_iter(&self) -> Vector3DIter {
68        Vector3DIter::new(self.bitangents,
69                          self.num_vertices as usize)
70    }
71
72    pub fn get_bitangent(&self, id: u32) -> Option<Vector3D> {
73        self.vertex_data(self.bitangents, id)
74    }
75
76    pub fn vertex_color_iter(&self, set_id: usize) -> Color4DIter {
77        Color4DIter::new(self.colors[set_id],
78                         self.num_vertices as usize)
79    }
80
81    pub fn get_vertex_color(&self, set_id: usize, id: u32) -> Option<Color4D> {
82        self.color_data(self.colors[set_id], id)
83    }
84
85    pub fn texture_coords_iter(&self, channel_id: usize) -> Vector3DIter {
86        Vector3DIter::new(self.texture_coords[channel_id],
87                          self.num_vertices as usize)
88    }
89
90    pub fn get_texture_coord(&self, channel_id: usize, id: u32) -> Option<Vector3D> {
91        self.vertex_data(self.texture_coords[channel_id], id)
92    }
93
94    pub fn num_faces(&self) -> u32 {
95        self.num_faces
96    }
97
98    pub fn face_iter(&self) -> FaceIter {
99        FaceIter::new(self.faces,
100                      self.num_faces as usize)
101    }
102
103    pub fn get_face(&self, id: u32) -> Option<Face> {
104        if id < self.num_faces {
105            unsafe { Some(Face::from_raw(self.faces.offset(id as isize))) }
106        } else {
107            None
108        }
109    }
110
111    pub fn num_bones(&self) -> u32 {
112        self.num_bones
113    }
114
115    pub fn bone_iter(&self) -> BoneIter {
116        BoneIter::new(self.bones as *const *const AiBone,
117                      self.num_bones as usize)
118    }
119
120    pub fn get_bone(&self, id: u32) -> Option<Bone> {
121        if id < self.num_bones {
122            unsafe { Some(Bone::from_raw(*(self.bones.offset(id as isize)))) }
123        } else {
124            None
125        }
126    }
127
128    #[inline]
129    fn vertex_data(&self, array: *mut AiVector3D, id: u32) -> Option<Vector3D> {
130        if id < self.num_vertices {
131            unsafe { Some(Vector3D::from_raw(array.offset(id as isize))) }
132        } else {
133            None
134        }
135    }
136
137    #[inline]
138    fn color_data(&self, array: *mut AiColor4D, id: u32) -> Option<Color4D> {
139        if id < self.num_vertices {
140            unsafe { Some(Color4D::from_raw(array.offset(id as isize))) }
141        } else {
142            None
143        }
144    }
145}
146
147impl<'a> Bone<'a> {
148    /// Returns the name of the bone.
149    pub fn name(&self) -> &str {
150        self.name.as_ref()
151    }
152
153    /// Returns the bones's offset transformation matrix.
154    pub fn offset_matrix(&self) -> Matrix4x4 {
155        Matrix4x4::from_raw(&self.offset_matrix)
156    }
157
158    pub fn num_weights(&self) -> u32 {
159        self.num_weights
160    }
161
162    pub fn weight_iter(&self) -> VertexWeightIter {
163        VertexWeightIter::new(self.weights as *const *const AiVertexWeight,
164                      self.num_weights as usize)
165    }
166
167    pub fn get_weight(&self, id: u32) -> Option<VertexWeight> {
168        if id < self.num_weights {
169            unsafe { Some(VertexWeight::from_raw(self.weights.offset(id as isize))) }
170        } else {
171            None
172        }
173    }
174}