1use crate::{
24 core::algebra::{Vector2, Vector3, Vector4},
25 scene::mesh::buffer::{
26 VertexAttributeDataType, VertexAttributeDescriptor, VertexAttributeUsage, VertexTrait,
27 },
28};
29use bytemuck::{Pod, Zeroable};
30use std::hash::{Hash, Hasher};
31
32#[derive(Copy, Clone, Debug, Default, Pod, Zeroable)]
34#[repr(C)] pub struct StaticVertex {
36 pub position: Vector3<f32>,
38 pub tex_coord: Vector2<f32>,
40 pub normal: Vector3<f32>,
42 pub tangent: Vector4<f32>,
44}
45
46impl StaticVertex {
47 pub fn from_pos_uv(position: Vector3<f32>, tex_coord: Vector2<f32>) -> Self {
49 Self {
50 position,
51 tex_coord,
52 normal: Vector3::new(0.0, 1.0, 0.0),
53 tangent: Vector4::default(),
54 }
55 }
56
57 pub fn from_pos_uv_normal(
59 position: Vector3<f32>,
60 tex_coord: Vector2<f32>,
61 normal: Vector3<f32>,
62 ) -> Self {
63 Self {
64 position,
65 tex_coord,
66 normal,
67 tangent: Vector4::default(),
68 }
69 }
70}
71
72impl VertexTrait for StaticVertex {
73 fn layout() -> &'static [VertexAttributeDescriptor] {
74 static LAYOUT: [VertexAttributeDescriptor; 4] = [
75 VertexAttributeDescriptor {
76 usage: VertexAttributeUsage::Position,
77 data_type: VertexAttributeDataType::F32,
78 size: 3,
79 divisor: 0,
80 shader_location: 0,
81 normalized: false,
82 },
83 VertexAttributeDescriptor {
84 usage: VertexAttributeUsage::TexCoord0,
85 data_type: VertexAttributeDataType::F32,
86 size: 2,
87 divisor: 0,
88 shader_location: 1,
89 normalized: false,
90 },
91 VertexAttributeDescriptor {
92 usage: VertexAttributeUsage::Normal,
93 data_type: VertexAttributeDataType::F32,
94 size: 3,
95 divisor: 0,
96 shader_location: 2,
97 normalized: false,
98 },
99 VertexAttributeDescriptor {
100 usage: VertexAttributeUsage::Tangent,
101 data_type: VertexAttributeDataType::F32,
102 size: 4,
103 divisor: 0,
104 shader_location: 3,
105 normalized: false,
106 },
107 ];
108 &LAYOUT
109 }
110}
111
112impl PartialEq for StaticVertex {
113 fn eq(&self, other: &Self) -> bool {
114 self.position == other.position
115 && self.tex_coord == other.tex_coord
116 && self.normal == other.normal
117 && self.tangent == other.tangent
118 }
119}
120
121impl Hash for StaticVertex {
125 fn hash<H: Hasher>(&self, state: &mut H) {
126 #[allow(unsafe_code)]
127 unsafe {
128 let bytes = self as *const Self as *const u8;
129 state.write(std::slice::from_raw_parts(
130 bytes,
131 std::mem::size_of::<Self>(),
132 ))
133 }
134 }
135}
136
137#[derive(Copy, Clone, Debug, Default)]
139#[repr(C)] pub struct AnimatedVertex {
141 pub position: Vector3<f32>,
143 pub tex_coord: Vector2<f32>,
145 pub normal: Vector3<f32>,
147 pub tangent: Vector4<f32>,
149 pub bone_weights: [f32; 4],
152 pub bone_indices: [u8; 4],
155}
156
157impl VertexTrait for AnimatedVertex {
158 fn layout() -> &'static [VertexAttributeDescriptor] {
159 &[
160 VertexAttributeDescriptor {
161 usage: VertexAttributeUsage::Position,
162 data_type: VertexAttributeDataType::F32,
163 size: 3,
164 divisor: 0,
165 shader_location: 0,
166 normalized: false,
167 },
168 VertexAttributeDescriptor {
169 usage: VertexAttributeUsage::TexCoord0,
170 data_type: VertexAttributeDataType::F32,
171 size: 2,
172 divisor: 0,
173 shader_location: 1,
174 normalized: false,
175 },
176 VertexAttributeDescriptor {
177 usage: VertexAttributeUsage::Normal,
178 data_type: VertexAttributeDataType::F32,
179 size: 3,
180 divisor: 0,
181 shader_location: 2,
182 normalized: false,
183 },
184 VertexAttributeDescriptor {
185 usage: VertexAttributeUsage::Tangent,
186 data_type: VertexAttributeDataType::F32,
187 size: 4,
188 divisor: 0,
189 shader_location: 3,
190 normalized: false,
191 },
192 VertexAttributeDescriptor {
193 usage: VertexAttributeUsage::BoneWeight,
194 data_type: VertexAttributeDataType::F32,
195 size: 4,
196 divisor: 0,
197 shader_location: 4,
198 normalized: false,
199 },
200 VertexAttributeDescriptor {
201 usage: VertexAttributeUsage::BoneIndices,
202 data_type: VertexAttributeDataType::U8,
203 size: 4,
204 divisor: 0,
205 shader_location: 5,
206 normalized: false,
207 },
208 ]
209 }
210}
211
212impl PartialEq for AnimatedVertex {
213 fn eq(&self, other: &Self) -> bool {
214 self.position == other.position
215 && self.tex_coord == other.tex_coord
216 && self.normal == other.normal
217 && self.tangent == other.tangent
218 && self.bone_weights == other.bone_weights
219 && self.bone_indices == other.bone_indices
220 }
221}
222
223impl Hash for AnimatedVertex {
227 fn hash<H: Hasher>(&self, state: &mut H) {
228 #[allow(unsafe_code)]
229 unsafe {
230 let bytes = self as *const Self as *const u8;
231 state.write(std::slice::from_raw_parts(
232 bytes,
233 std::mem::size_of::<Self>(),
234 ))
235 }
236 }
237}
238
239#[derive(Copy, Clone, Debug, Default)]
241#[repr(C)] pub struct SimpleVertex {
243 pub position: Vector3<f32>,
245}
246
247impl SimpleVertex {
248 pub fn new(x: f32, y: f32, z: f32) -> Self {
250 Self {
251 position: Vector3::new(x, y, z),
252 }
253 }
254}
255
256impl VertexTrait for SimpleVertex {
257 fn layout() -> &'static [VertexAttributeDescriptor] {
258 &[VertexAttributeDescriptor {
259 usage: VertexAttributeUsage::Position,
260 data_type: VertexAttributeDataType::F32,
261 size: 3,
262 divisor: 0,
263 shader_location: 0,
264 normalized: false,
265 }]
266 }
267}
268
269impl PartialEq for SimpleVertex {
270 fn eq(&self, other: &Self) -> bool {
271 self.position == other.position
272 }
273}
274
275impl Hash for SimpleVertex {
279 fn hash<H: Hasher>(&self, state: &mut H) {
280 #[allow(unsafe_code)]
281 unsafe {
282 let bytes = self as *const Self as *const u8;
283 state.write(std::slice::from_raw_parts(
284 bytes,
285 std::mem::size_of::<Self>(),
286 ))
287 }
288 }
289}