1use alloc::sync::Arc;
2use bevy_derive::EnumVariantMeta;
3use bevy_ecs::resource::Resource;
4use bevy_math::{vec2, Vec2, Vec3, Vec3A, Vec3Swizzles};
5#[cfg(feature = "serialize")]
6use bevy_platform::collections::HashMap;
7use bevy_platform::collections::HashSet;
8use bevy_shape::{Aabb2d, Aabb3d, BoundingVolume};
9use bytemuck::{bytes_of, cast_slice};
10use core::hash::{Hash, Hasher};
11#[cfg(feature = "serialize")]
12use serde::{Deserialize, Serialize};
13use thiserror::Error;
14use wgpu_types::{BufferAddress, VertexAttribute, VertexFormat, VertexStepMode};
15
16use crate::MeshAttributeCompressionFlags;
17
18#[derive(Debug, Clone, Copy, PartialEq)]
19pub struct MeshVertexAttribute {
20 pub name: &'static str,
22
23 pub id: MeshVertexAttributeId,
27
28 pub format: VertexFormat,
30}
31
32#[cfg(feature = "serialize")]
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub(crate) struct SerializedMeshVertexAttribute {
35 pub(crate) name: String,
36 pub(crate) id: MeshVertexAttributeId,
37 pub(crate) format: VertexFormat,
38}
39
40#[cfg(feature = "serialize")]
41impl SerializedMeshVertexAttribute {
42 pub(crate) fn from_mesh_vertex_attribute(attribute: MeshVertexAttribute) -> Self {
43 Self {
44 name: attribute.name.to_string(),
45 id: attribute.id,
46 format: attribute.format,
47 }
48 }
49
50 pub(crate) fn try_into_mesh_vertex_attribute(
51 self,
52 possible_attributes: &HashMap<Box<str>, MeshVertexAttribute>,
53 ) -> Option<MeshVertexAttribute> {
54 let attr = possible_attributes.get(self.name.as_str())?;
55 if attr.id == self.id {
56 Some(*attr)
57 } else {
58 None
59 }
60 }
61}
62
63impl MeshVertexAttribute {
64 pub const fn new(name: &'static str, id: u64, format: VertexFormat) -> Self {
65 Self {
66 name,
67 id: MeshVertexAttributeId(id),
68 format,
69 }
70 }
71
72 pub const fn at_shader_location(&self, shader_location: u32) -> VertexAttributeDescriptor {
73 VertexAttributeDescriptor::new(shader_location, self.id, self.name)
74 }
75}
76
77#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
78#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
79pub struct MeshVertexAttributeId(u64);
80
81impl From<MeshVertexAttribute> for MeshVertexAttributeId {
82 fn from(attribute: MeshVertexAttribute) -> Self {
83 attribute.id
84 }
85}
86
87#[derive(Debug, Clone, Hash, Eq, PartialEq)]
88pub struct MeshVertexBufferLayout {
89 pub(crate) attribute_ids: Vec<MeshVertexAttributeId>,
90 pub(crate) attribute_compression: MeshAttributeCompressionFlags,
91 pub(crate) layout: VertexBufferLayout,
92}
93
94impl MeshVertexBufferLayout {
95 pub fn new(
96 attribute_ids: Vec<MeshVertexAttributeId>,
97 layout: VertexBufferLayout,
98 attribute_compression: MeshAttributeCompressionFlags,
99 ) -> Self {
100 Self {
101 attribute_ids,
102 attribute_compression,
103 layout,
104 }
105 }
106
107 #[inline]
108 pub fn contains(&self, attribute_id: impl Into<MeshVertexAttributeId>) -> bool {
109 self.attribute_ids.contains(&attribute_id.into())
110 }
111
112 #[inline]
113 pub fn attribute_ids(&self) -> &[MeshVertexAttributeId] {
114 &self.attribute_ids
115 }
116
117 #[inline]
118 pub fn layout(&self) -> &VertexBufferLayout {
119 &self.layout
120 }
121
122 pub fn get_attribute_compression(&self) -> MeshAttributeCompressionFlags {
123 self.attribute_compression
124 }
125
126 pub fn get_layout(
127 &self,
128 attribute_descriptors: &[VertexAttributeDescriptor],
129 ) -> Result<VertexBufferLayout, MissingVertexAttributeError> {
130 let mut attributes = Vec::with_capacity(attribute_descriptors.len());
131 for attribute_descriptor in attribute_descriptors {
132 if let Some(index) = self
133 .attribute_ids
134 .iter()
135 .position(|id| *id == attribute_descriptor.id)
136 {
137 let layout_attribute = &self.layout.attributes[index];
138 attributes.push(VertexAttribute {
139 format: layout_attribute.format,
140 offset: layout_attribute.offset,
141 shader_location: attribute_descriptor.shader_location,
142 });
143 } else {
144 return Err(MissingVertexAttributeError {
145 id: attribute_descriptor.id,
146 name: attribute_descriptor.name,
147 pipeline_type: None,
148 });
149 }
150 }
151
152 Ok(VertexBufferLayout {
153 array_stride: self.layout.array_stride,
154 step_mode: self.layout.step_mode,
155 attributes,
156 })
157 }
158}
159
160#[derive(Error, Debug)]
161#[error("Mesh is missing requested attribute: {name} ({id:?}, pipeline type: {pipeline_type:?})")]
162pub struct MissingVertexAttributeError {
163 pub pipeline_type: Option<&'static str>,
164 id: MeshVertexAttributeId,
165 name: &'static str,
166}
167
168pub struct VertexAttributeDescriptor {
169 pub shader_location: u32,
170 pub id: MeshVertexAttributeId,
171 name: &'static str,
172}
173
174impl VertexAttributeDescriptor {
175 pub const fn new(shader_location: u32, id: MeshVertexAttributeId, name: &'static str) -> Self {
176 Self {
177 shader_location,
178 id,
179 name,
180 }
181 }
182}
183
184#[derive(Debug, Clone, PartialEq)]
185pub(crate) struct MeshAttributeData {
186 pub(crate) attribute: MeshVertexAttribute,
187 pub(crate) values: VertexAttributeValues,
188}
189
190#[cfg(feature = "serialize")]
191#[derive(Debug, Clone, Serialize, Deserialize)]
192pub(crate) struct SerializedMeshAttributeData {
193 pub(crate) attribute: SerializedMeshVertexAttribute,
194 pub(crate) values: VertexAttributeValues,
195}
196
197#[cfg(feature = "serialize")]
198impl SerializedMeshAttributeData {
199 pub(crate) fn from_mesh_attribute_data(data: MeshAttributeData) -> Self {
200 Self {
201 attribute: SerializedMeshVertexAttribute::from_mesh_vertex_attribute(data.attribute),
202 values: data.values,
203 }
204 }
205
206 pub(crate) fn try_into_mesh_attribute_data(
207 self,
208 possible_attributes: &HashMap<Box<str>, MeshVertexAttribute>,
209 ) -> Option<MeshAttributeData> {
210 let attribute = self
211 .attribute
212 .try_into_mesh_vertex_attribute(possible_attributes)?;
213 Some(MeshAttributeData {
214 attribute,
215 values: self.values,
216 })
217 }
218}
219
220#[inline]
235pub fn triangle_area_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
236 let (a, b, c) = (Vec3::from(a), Vec3::from(b), Vec3::from(c));
237 (b - a).cross(c - a).into()
238}
239
240#[inline]
242pub fn triangle_normal(a: [f32; 3], b: [f32; 3], c: [f32; 3]) -> [f32; 3] {
243 let (a, b, c) = (Vec3::from(a), Vec3::from(b), Vec3::from(c));
244 (b - a).cross(c - a).normalize_or_zero().into()
245}
246
247#[derive(Clone, Copy, Debug, PartialEq, Eq)]
249#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
250pub enum AttributeQuantization {
251 Unorm8,
252 Snorm8,
253 Unorm16,
254 Snorm16,
255 Float16,
256}
257
258impl AttributeQuantization {
259 pub(crate) fn quantize_f32_values<const N: usize>(
261 &self,
262 values: &[[f32; N]],
263 ) -> VertexAttributeValues {
264 const {
265 assert!(N == 1 || N == 2 || N == 4);
266 }
267 match self {
268 AttributeQuantization::Unorm8 => {
269 let values = values.iter().map(|v| arr_f32_to_unorm8(*v)).collect();
270 match N {
271 1 => VertexAttributeValues::Unorm8(bytemuck::cast_vec(values)),
272 2 => VertexAttributeValues::Unorm8x2(bytemuck::cast_vec(values)),
273 4 => VertexAttributeValues::Unorm8x4(bytemuck::cast_vec(values)),
274 _ => unreachable!(),
275 }
276 }
277 AttributeQuantization::Snorm8 => {
278 let values = values.iter().map(|v| arr_f32_to_snorm8(*v)).collect();
279 match N {
280 1 => VertexAttributeValues::Snorm8(bytemuck::cast_vec(values)),
281 2 => VertexAttributeValues::Snorm8x2(bytemuck::cast_vec(values)),
282 4 => VertexAttributeValues::Snorm8x4(bytemuck::cast_vec(values)),
283 _ => unreachable!(),
284 }
285 }
286 AttributeQuantization::Unorm16 => {
287 let values = values.iter().map(|v| arr_f32_to_unorm16(*v)).collect();
288 match N {
289 1 => VertexAttributeValues::Unorm16(bytemuck::cast_vec(values)),
290 2 => VertexAttributeValues::Unorm16x2(bytemuck::cast_vec(values)),
291 4 => VertexAttributeValues::Unorm16x4(bytemuck::cast_vec(values)),
292 _ => unreachable!(),
293 }
294 }
295 AttributeQuantization::Snorm16 => {
296 let values = values.iter().map(|v| arr_f32_to_snorm16(*v)).collect();
297 match N {
298 1 => VertexAttributeValues::Snorm16(bytemuck::cast_vec(values)),
299 2 => VertexAttributeValues::Snorm16x2(bytemuck::cast_vec(values)),
300 4 => VertexAttributeValues::Snorm16x4(bytemuck::cast_vec(values)),
301 _ => unreachable!(),
302 }
303 }
304 AttributeQuantization::Float16 => {
305 let values = values.iter().map(|v| arr_f32_to_float16(*v)).collect();
306 match N {
307 1 => VertexAttributeValues::Float16(bytemuck::cast_vec(values)),
308 2 => VertexAttributeValues::Float16x2(bytemuck::cast_vec(values)),
309 4 => VertexAttributeValues::Float16x4(bytemuck::cast_vec(values)),
310 _ => unreachable!(),
311 }
312 }
313 }
314 }
315}
316
317#[derive(Clone, Debug, EnumVariantMeta, PartialEq)]
320#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
321pub enum VertexAttributeValues {
322 Uint8(Vec<u8>),
324 Uint8x2(Vec<[u8; 2]>),
326 Uint8x4(Vec<[u8; 4]>),
328 Sint8(Vec<i8>),
330 Sint8x2(Vec<[i8; 2]>),
332 Sint8x4(Vec<[i8; 4]>),
334 Unorm8(Vec<u8>),
336 Unorm8x2(Vec<[u8; 2]>),
338 Unorm8x4(Vec<[u8; 4]>),
340 Snorm8(Vec<i8>),
342 Snorm8x2(Vec<[i8; 2]>),
344 Snorm8x4(Vec<[i8; 4]>),
346 Uint16(Vec<u16>),
348 Uint16x2(Vec<[u16; 2]>),
350 Uint16x4(Vec<[u16; 4]>),
352 Sint16(Vec<i16>),
354 Sint16x2(Vec<[i16; 2]>),
356 Sint16x4(Vec<[i16; 4]>),
358 Unorm16(Vec<u16>),
360 Unorm16x2(Vec<[u16; 2]>),
362 Unorm16x4(Vec<[u16; 4]>),
364 Snorm16(Vec<i16>),
366 Snorm16x2(Vec<[i16; 2]>),
368 Snorm16x4(Vec<[i16; 4]>),
370 Float16(Vec<half::f16>),
372 Float16x2(Vec<[half::f16; 2]>),
374 Float16x4(Vec<[half::f16; 4]>),
376 Float32(Vec<f32>),
378 Float32x2(Vec<[f32; 2]>),
380 Float32x3(Vec<[f32; 3]>),
382 Float32x4(Vec<[f32; 4]>),
384 Uint32(Vec<u32>),
386 Uint32x2(Vec<[u32; 2]>),
388 Uint32x3(Vec<[u32; 3]>),
390 Uint32x4(Vec<[u32; 4]>),
392 Sint32(Vec<i32>),
394 Sint32x2(Vec<[i32; 2]>),
396 Sint32x3(Vec<[i32; 3]>),
398 Sint32x4(Vec<[i32; 4]>),
400 Float64(Vec<f64>),
402 Float64x2(Vec<[f64; 2]>),
404 Float64x3(Vec<[f64; 3]>),
406 Float64x4(Vec<[f64; 4]>),
408 Unorm10_10_10_2(Vec<u32>),
410 Unorm8x4Bgra(Vec<[u8; 4]>),
412}
413
414impl VertexAttributeValues {
415 pub(crate) fn new(format: VertexFormat) -> Self {
417 match format {
418 VertexFormat::Uint8x2 => VertexAttributeValues::Uint8x2(Vec::new()),
419 VertexFormat::Uint8x4 => VertexAttributeValues::Uint8x4(Vec::new()),
420 VertexFormat::Sint8x2 => VertexAttributeValues::Sint8x2(Vec::new()),
421 VertexFormat::Sint8x4 => VertexAttributeValues::Sint8x4(Vec::new()),
422 VertexFormat::Unorm8x2 => VertexAttributeValues::Unorm8x2(Vec::new()),
423 VertexFormat::Unorm8x4 => VertexAttributeValues::Unorm8x4(Vec::new()),
424 VertexFormat::Snorm8x2 => VertexAttributeValues::Snorm8x2(Vec::new()),
425 VertexFormat::Snorm8x4 => VertexAttributeValues::Snorm8x4(Vec::new()),
426 VertexFormat::Uint16x2 => VertexAttributeValues::Uint16x2(Vec::new()),
427 VertexFormat::Uint16x4 => VertexAttributeValues::Uint16x4(Vec::new()),
428 VertexFormat::Sint16x2 => VertexAttributeValues::Sint16x2(Vec::new()),
429 VertexFormat::Sint16x4 => VertexAttributeValues::Sint16x4(Vec::new()),
430 VertexFormat::Unorm16x2 => VertexAttributeValues::Unorm16x2(Vec::new()),
431 VertexFormat::Unorm16x4 => VertexAttributeValues::Unorm16x4(Vec::new()),
432 VertexFormat::Snorm16x2 => VertexAttributeValues::Snorm16x2(Vec::new()),
433 VertexFormat::Snorm16x4 => VertexAttributeValues::Snorm16x4(Vec::new()),
434 VertexFormat::Float32 => VertexAttributeValues::Float32(Vec::new()),
435 VertexFormat::Float32x2 => VertexAttributeValues::Float32x2(Vec::new()),
436 VertexFormat::Float32x3 => VertexAttributeValues::Float32x3(Vec::new()),
437 VertexFormat::Float32x4 => VertexAttributeValues::Float32x4(Vec::new()),
438 VertexFormat::Uint32 => VertexAttributeValues::Uint32(Vec::new()),
439 VertexFormat::Uint32x2 => VertexAttributeValues::Uint32x2(Vec::new()),
440 VertexFormat::Uint32x3 => VertexAttributeValues::Uint32x3(Vec::new()),
441 VertexFormat::Uint32x4 => VertexAttributeValues::Uint32x4(Vec::new()),
442 VertexFormat::Sint32 => VertexAttributeValues::Sint32(Vec::new()),
443 VertexFormat::Sint32x2 => VertexAttributeValues::Sint32x2(Vec::new()),
444 VertexFormat::Sint32x3 => VertexAttributeValues::Sint32x3(Vec::new()),
445 VertexFormat::Sint32x4 => VertexAttributeValues::Sint32x4(Vec::new()),
446 VertexFormat::Uint8 => VertexAttributeValues::Uint8(Vec::new()),
447 VertexFormat::Sint8 => VertexAttributeValues::Sint8(Vec::new()),
448 VertexFormat::Snorm8 => VertexAttributeValues::Snorm8(Vec::new()),
449 VertexFormat::Unorm8 => VertexAttributeValues::Unorm8(Vec::new()),
450 VertexFormat::Uint16 => VertexAttributeValues::Uint16(Vec::new()),
451 VertexFormat::Sint16 => VertexAttributeValues::Sint16(Vec::new()),
452 VertexFormat::Snorm16 => VertexAttributeValues::Snorm16(Vec::new()),
453 VertexFormat::Unorm16 => VertexAttributeValues::Unorm16(Vec::new()),
454 VertexFormat::Float16 => VertexAttributeValues::Float16(Vec::new()),
455 VertexFormat::Float16x2 => VertexAttributeValues::Float16x2(Vec::new()),
456 VertexFormat::Float16x4 => VertexAttributeValues::Float16x4(Vec::new()),
457 VertexFormat::Float64 => VertexAttributeValues::Float64(Vec::new()),
458 VertexFormat::Float64x2 => VertexAttributeValues::Float64x2(Vec::new()),
459 VertexFormat::Float64x3 => VertexAttributeValues::Float64x3(Vec::new()),
460 VertexFormat::Float64x4 => VertexAttributeValues::Float64x4(Vec::new()),
461 VertexFormat::Unorm8x4Bgra => VertexAttributeValues::Unorm8x4Bgra(Vec::new()),
462 VertexFormat::Unorm10_10_10_2 => VertexAttributeValues::Unorm10_10_10_2(Vec::new()),
463 }
464 }
465
466 #[expect(
469 clippy::match_same_arms,
470 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
471 )]
472 pub fn len(&self) -> usize {
473 match self {
474 VertexAttributeValues::Float32(values) => values.len(),
475 VertexAttributeValues::Sint32(values) => values.len(),
476 VertexAttributeValues::Uint32(values) => values.len(),
477 VertexAttributeValues::Float32x2(values) => values.len(),
478 VertexAttributeValues::Sint32x2(values) => values.len(),
479 VertexAttributeValues::Uint32x2(values) => values.len(),
480 VertexAttributeValues::Float32x3(values) => values.len(),
481 VertexAttributeValues::Sint32x3(values) => values.len(),
482 VertexAttributeValues::Uint32x3(values) => values.len(),
483 VertexAttributeValues::Float32x4(values) => values.len(),
484 VertexAttributeValues::Sint32x4(values) => values.len(),
485 VertexAttributeValues::Uint32x4(values) => values.len(),
486 VertexAttributeValues::Sint16x2(values) => values.len(),
487 VertexAttributeValues::Snorm16x2(values) => values.len(),
488 VertexAttributeValues::Uint16x2(values) => values.len(),
489 VertexAttributeValues::Unorm16x2(values) => values.len(),
490 VertexAttributeValues::Sint16x4(values) => values.len(),
491 VertexAttributeValues::Snorm16x4(values) => values.len(),
492 VertexAttributeValues::Uint16x4(values) => values.len(),
493 VertexAttributeValues::Unorm16x4(values) => values.len(),
494 VertexAttributeValues::Sint8x2(values) => values.len(),
495 VertexAttributeValues::Snorm8x2(values) => values.len(),
496 VertexAttributeValues::Uint8x2(values) => values.len(),
497 VertexAttributeValues::Unorm8x2(values) => values.len(),
498 VertexAttributeValues::Sint8x4(values) => values.len(),
499 VertexAttributeValues::Snorm8x4(values) => values.len(),
500 VertexAttributeValues::Uint8x4(values) => values.len(),
501 VertexAttributeValues::Unorm8x4(values) => values.len(),
502 VertexAttributeValues::Uint8(values) => values.len(),
503 VertexAttributeValues::Sint8(values) => values.len(),
504 VertexAttributeValues::Unorm8(values) => values.len(),
505 VertexAttributeValues::Snorm8(values) => values.len(),
506 VertexAttributeValues::Uint16(values) => values.len(),
507 VertexAttributeValues::Sint16(values) => values.len(),
508 VertexAttributeValues::Unorm16(values) => values.len(),
509 VertexAttributeValues::Snorm16(values) => values.len(),
510 VertexAttributeValues::Float16(values) => values.len(),
511 VertexAttributeValues::Float16x2(values) => values.len(),
512 VertexAttributeValues::Float16x4(values) => values.len(),
513 VertexAttributeValues::Float64(values) => values.len(),
514 VertexAttributeValues::Float64x2(values) => values.len(),
515 VertexAttributeValues::Float64x3(values) => values.len(),
516 VertexAttributeValues::Float64x4(values) => values.len(),
517 VertexAttributeValues::Unorm10_10_10_2(values) => values.len(),
518 VertexAttributeValues::Unorm8x4Bgra(values) => values.len(),
519 }
520 }
521
522 pub fn is_empty(&self) -> bool {
524 self.len() == 0
525 }
526
527 pub fn as_float3(&self) -> Option<&[[f32; 3]]> {
529 match self {
530 VertexAttributeValues::Float32x3(values) => Some(values),
531 _ => None,
532 }
533 }
534
535 #[expect(
539 clippy::match_same_arms,
540 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
541 )]
542 pub fn get_bytes(&self) -> &[u8] {
543 match self {
544 VertexAttributeValues::Float32(values) => cast_slice(values),
545 VertexAttributeValues::Sint32(values) => cast_slice(values),
546 VertexAttributeValues::Uint32(values) => cast_slice(values),
547 VertexAttributeValues::Float32x2(values) => cast_slice(values),
548 VertexAttributeValues::Sint32x2(values) => cast_slice(values),
549 VertexAttributeValues::Uint32x2(values) => cast_slice(values),
550 VertexAttributeValues::Float32x3(values) => cast_slice(values),
551 VertexAttributeValues::Sint32x3(values) => cast_slice(values),
552 VertexAttributeValues::Uint32x3(values) => cast_slice(values),
553 VertexAttributeValues::Float32x4(values) => cast_slice(values),
554 VertexAttributeValues::Sint32x4(values) => cast_slice(values),
555 VertexAttributeValues::Uint32x4(values) => cast_slice(values),
556 VertexAttributeValues::Sint16x2(values) => cast_slice(values),
557 VertexAttributeValues::Snorm16x2(values) => cast_slice(values),
558 VertexAttributeValues::Uint16x2(values) => cast_slice(values),
559 VertexAttributeValues::Unorm16x2(values) => cast_slice(values),
560 VertexAttributeValues::Sint16x4(values) => cast_slice(values),
561 VertexAttributeValues::Snorm16x4(values) => cast_slice(values),
562 VertexAttributeValues::Uint16x4(values) => cast_slice(values),
563 VertexAttributeValues::Unorm16x4(values) => cast_slice(values),
564 VertexAttributeValues::Sint8x2(values) => cast_slice(values),
565 VertexAttributeValues::Snorm8x2(values) => cast_slice(values),
566 VertexAttributeValues::Uint8x2(values) => cast_slice(values),
567 VertexAttributeValues::Unorm8x2(values) => cast_slice(values),
568 VertexAttributeValues::Sint8x4(values) => cast_slice(values),
569 VertexAttributeValues::Snorm8x4(values) => cast_slice(values),
570 VertexAttributeValues::Uint8x4(values) => cast_slice(values),
571 VertexAttributeValues::Unorm8x4(values) => cast_slice(values),
572 VertexAttributeValues::Uint8(values) => cast_slice(values),
573 VertexAttributeValues::Sint8(values) => cast_slice(values),
574 VertexAttributeValues::Unorm8(values) => cast_slice(values),
575 VertexAttributeValues::Snorm8(values) => cast_slice(values),
576 VertexAttributeValues::Uint16(values) => cast_slice(values),
577 VertexAttributeValues::Sint16(values) => cast_slice(values),
578 VertexAttributeValues::Unorm16(values) => cast_slice(values),
579 VertexAttributeValues::Snorm16(values) => cast_slice(values),
580 VertexAttributeValues::Float16(values) => cast_slice(values),
581 VertexAttributeValues::Float16x2(values) => cast_slice(values),
582 VertexAttributeValues::Float16x4(values) => cast_slice(values),
583 VertexAttributeValues::Float64(values) => cast_slice(values),
584 VertexAttributeValues::Float64x2(values) => cast_slice(values),
585 VertexAttributeValues::Float64x3(values) => cast_slice(values),
586 VertexAttributeValues::Float64x4(values) => cast_slice(values),
587 VertexAttributeValues::Unorm10_10_10_2(values) => cast_slice(values),
588 VertexAttributeValues::Unorm8x4Bgra(values) => cast_slice(values),
589 }
590 }
591
592 pub(crate) fn create_quantized_values(
595 &self,
596 quantization: AttributeQuantization,
597 ) -> Option<VertexAttributeValues> {
598 match self {
599 VertexAttributeValues::Float32(values) => {
600 Some(quantization.quantize_f32_values::<1>(bytemuck::must_cast_slice(values)))
601 }
602 VertexAttributeValues::Float32x2(values) => {
603 Some(quantization.quantize_f32_values::<2>(values))
604 }
605 VertexAttributeValues::Float32x4(values) => {
606 Some(quantization.quantize_f32_values::<4>(values))
607 }
608 _ => None,
609 }
610 }
611
612 pub(crate) fn create_octahedral_encode_normals(&self) -> Option<VertexAttributeValues> {
614 match &self {
615 VertexAttributeValues::Float32x3(uncompressed_values) => {
616 let mut values = Vec::<[i16; 2]>::with_capacity(uncompressed_values.len());
617 for value in uncompressed_values {
618 let encoded = octahedral_encode_signed(Vec3::from_array(*value).normalize());
619 values.push(arr_f32_to_snorm16(encoded.to_array()));
620 }
621 Some(VertexAttributeValues::Snorm16x2(values))
622 }
623 _ => None,
624 }
625 }
626
627 pub(crate) fn create_octahedral_encode_tangents(&self) -> Option<VertexAttributeValues> {
629 match &self {
630 VertexAttributeValues::Float32x4(uncompressed_values) => {
631 let mut values = Vec::<[i16; 2]>::with_capacity(uncompressed_values.len());
632 for value in uncompressed_values {
633 let encoded = octahedral_encode_tangent(
634 Vec3::from_array([value[0], value[1], value[2]]).normalize(),
635 value[3],
636 );
637 values.push(arr_f32_to_snorm16(encoded.to_array()));
638 }
639 Some(VertexAttributeValues::Snorm16x2(values))
640 }
641 _ => None,
642 }
643 }
644
645 pub(crate) fn create_compressed_positions(
647 &self,
648 aabb: Aabb3d,
649 ) -> Option<VertexAttributeValues> {
650 let VertexAttributeValues::Float32x3(uncompressed_values) = self else {
652 return None;
653 };
654 let mut values = Vec::<[i16; 4]>::with_capacity(uncompressed_values.len());
655 let scale = 1.0 / aabb.half_size();
656 let scale = Vec3A::select(scale.is_nan_mask(), Vec3A::ZERO, scale);
657 for val in uncompressed_values {
658 let mut val = Vec3A::from_array(*val);
659 val = (val - aabb.center()) * scale;
660 let val = arr_f32_to_snorm16(val.extend(0.0).to_array());
661 values.push(val);
662 }
663 Some(VertexAttributeValues::Snorm16x4(values))
664 }
665
666 pub(crate) fn create_compressed_uvs(&self, range: Aabb2d) -> Option<VertexAttributeValues> {
668 let VertexAttributeValues::Float32x2(uncompressed_values) = self else {
670 return None;
671 };
672 let mut values = Vec::<[u16; 2]>::with_capacity(uncompressed_values.len());
673 let scale = 1.0 / (range.max - range.min);
674 let scale = Vec2::select(scale.is_nan_mask(), Vec2::ZERO, scale);
675 for val in uncompressed_values {
676 let mut val = Vec2::from_array(*val);
677 val = (val - range.min) * scale;
678 values.push(arr_f32_to_unorm16(val.to_array()));
679 }
680 Some(VertexAttributeValues::Unorm16x2(values))
681 }
682
683 #[expect(
684 clippy::match_same_arms,
685 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
686 )]
687 pub(crate) fn get_bytes_at(&self, i: usize) -> &[u8] {
688 match self {
689 VertexAttributeValues::Float32(values) => bytes_of(&values[i]),
690 VertexAttributeValues::Sint32(values) => bytes_of(&values[i]),
691 VertexAttributeValues::Uint32(values) => bytes_of(&values[i]),
692 VertexAttributeValues::Float32x2(values) => bytes_of(&values[i]),
693 VertexAttributeValues::Sint32x2(values) => bytes_of(&values[i]),
694 VertexAttributeValues::Uint32x2(values) => bytes_of(&values[i]),
695 VertexAttributeValues::Float32x3(values) => bytes_of(&values[i]),
696 VertexAttributeValues::Sint32x3(values) => bytes_of(&values[i]),
697 VertexAttributeValues::Uint32x3(values) => bytes_of(&values[i]),
698 VertexAttributeValues::Float32x4(values) => bytes_of(&values[i]),
699 VertexAttributeValues::Sint32x4(values) => bytes_of(&values[i]),
700 VertexAttributeValues::Uint32x4(values) => bytes_of(&values[i]),
701 VertexAttributeValues::Sint16x2(values) => bytes_of(&values[i]),
702 VertexAttributeValues::Snorm16x2(values) => bytes_of(&values[i]),
703 VertexAttributeValues::Uint16x2(values) => bytes_of(&values[i]),
704 VertexAttributeValues::Unorm16x2(values) => bytes_of(&values[i]),
705 VertexAttributeValues::Sint16x4(values) => bytes_of(&values[i]),
706 VertexAttributeValues::Snorm16x4(values) => bytes_of(&values[i]),
707 VertexAttributeValues::Uint16x4(values) => bytes_of(&values[i]),
708 VertexAttributeValues::Unorm16x4(values) => bytes_of(&values[i]),
709 VertexAttributeValues::Sint8x2(values) => bytes_of(&values[i]),
710 VertexAttributeValues::Snorm8x2(values) => bytes_of(&values[i]),
711 VertexAttributeValues::Uint8x2(values) => bytes_of(&values[i]),
712 VertexAttributeValues::Unorm8x2(values) => bytes_of(&values[i]),
713 VertexAttributeValues::Sint8x4(values) => bytes_of(&values[i]),
714 VertexAttributeValues::Snorm8x4(values) => bytes_of(&values[i]),
715 VertexAttributeValues::Uint8x4(values) => bytes_of(&values[i]),
716 VertexAttributeValues::Unorm8x4(values) => bytes_of(&values[i]),
717 VertexAttributeValues::Uint8(values) => bytes_of(&values[i]),
718 VertexAttributeValues::Sint8(values) => bytes_of(&values[i]),
719 VertexAttributeValues::Unorm8(values) => bytes_of(&values[i]),
720 VertexAttributeValues::Snorm8(values) => bytes_of(&values[i]),
721 VertexAttributeValues::Uint16(values) => bytes_of(&values[i]),
722 VertexAttributeValues::Sint16(values) => bytes_of(&values[i]),
723 VertexAttributeValues::Unorm16(values) => bytes_of(&values[i]),
724 VertexAttributeValues::Snorm16(values) => bytes_of(&values[i]),
725 VertexAttributeValues::Float16(values) => bytes_of(&values[i]),
726 VertexAttributeValues::Float16x2(values) => bytes_of(&values[i]),
727 VertexAttributeValues::Float16x4(values) => bytes_of(&values[i]),
728 VertexAttributeValues::Float64(values) => bytes_of(&values[i]),
729 VertexAttributeValues::Float64x2(values) => bytes_of(&values[i]),
730 VertexAttributeValues::Float64x3(values) => bytes_of(&values[i]),
731 VertexAttributeValues::Float64x4(values) => bytes_of(&values[i]),
732 VertexAttributeValues::Unorm10_10_10_2(values) => bytes_of(&values[i]),
733 VertexAttributeValues::Unorm8x4Bgra(values) => bytes_of(&values[i]),
734 }
735 }
736
737 #[expect(
738 clippy::match_same_arms,
739 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
740 )]
741 pub(crate) fn push_from(&mut self, source: &VertexAttributeValues, i: usize) {
742 match (self, source) {
743 (VertexAttributeValues::Float32(this), VertexAttributeValues::Float32(source)) => {
744 this.push(source[i]);
745 }
746 (VertexAttributeValues::Float32(_), _) => panic!("Mismatched vertex attribute values"),
747 (VertexAttributeValues::Sint32(this), VertexAttributeValues::Sint32(source)) => {
748 this.push(source[i]);
749 }
750 (VertexAttributeValues::Sint32(_), _) => panic!("Mismatched vertex attribute values"),
751 (VertexAttributeValues::Uint32(this), VertexAttributeValues::Uint32(source)) => {
752 this.push(source[i]);
753 }
754 (VertexAttributeValues::Uint32(_), _) => panic!("Mismatched vertex attribute values"),
755 (VertexAttributeValues::Float32x2(this), VertexAttributeValues::Float32x2(source)) => {
756 this.push(source[i]);
757 }
758 (VertexAttributeValues::Float32x2(_), _) => {
759 panic!("Mismatched vertex attribute values")
760 }
761 (VertexAttributeValues::Sint32x2(this), VertexAttributeValues::Sint32x2(source)) => {
762 this.push(source[i]);
763 }
764 (VertexAttributeValues::Sint32x2(_), _) => panic!("Mismatched vertex attribute values"),
765 (VertexAttributeValues::Uint32x2(this), VertexAttributeValues::Uint32x2(source)) => {
766 this.push(source[i]);
767 }
768 (VertexAttributeValues::Uint32x2(_), _) => panic!("Mismatched vertex attribute values"),
769 (VertexAttributeValues::Float32x3(this), VertexAttributeValues::Float32x3(source)) => {
770 this.push(source[i]);
771 }
772 (VertexAttributeValues::Float32x3(_), _) => {
773 panic!("Mismatched vertex attribute values")
774 }
775 (VertexAttributeValues::Sint32x3(this), VertexAttributeValues::Sint32x3(source)) => {
776 this.push(source[i]);
777 }
778 (VertexAttributeValues::Sint32x3(_), _) => panic!("Mismatched vertex attribute values"),
779 (VertexAttributeValues::Uint32x3(this), VertexAttributeValues::Uint32x3(source)) => {
780 this.push(source[i]);
781 }
782 (VertexAttributeValues::Uint32x3(_), _) => panic!("Mismatched vertex attribute values"),
783 (VertexAttributeValues::Float32x4(this), VertexAttributeValues::Float32x4(source)) => {
784 this.push(source[i]);
785 }
786 (VertexAttributeValues::Float32x4(_), _) => {
787 panic!("Mismatched vertex attribute values")
788 }
789 (VertexAttributeValues::Sint32x4(this), VertexAttributeValues::Sint32x4(source)) => {
790 this.push(source[i]);
791 }
792 (VertexAttributeValues::Sint32x4(_), _) => panic!("Mismatched vertex attribute values"),
793 (VertexAttributeValues::Uint32x4(this), VertexAttributeValues::Uint32x4(source)) => {
794 this.push(source[i]);
795 }
796 (VertexAttributeValues::Uint32x4(_), _) => panic!("Mismatched vertex attribute values"),
797 (VertexAttributeValues::Sint16x2(this), VertexAttributeValues::Sint16x2(source)) => {
798 this.push(source[i]);
799 }
800 (VertexAttributeValues::Sint16x2(_), _) => panic!("Mismatched vertex attribute values"),
801 (VertexAttributeValues::Snorm16x2(this), VertexAttributeValues::Snorm16x2(source)) => {
802 this.push(source[i]);
803 }
804 (VertexAttributeValues::Snorm16x2(_), _) => {
805 panic!("Mismatched vertex attribute values")
806 }
807 (VertexAttributeValues::Uint16x2(this), VertexAttributeValues::Uint16x2(source)) => {
808 this.push(source[i]);
809 }
810 (VertexAttributeValues::Uint16x2(_), _) => panic!("Mismatched vertex attribute values"),
811 (VertexAttributeValues::Unorm16x2(this), VertexAttributeValues::Unorm16x2(source)) => {
812 this.push(source[i]);
813 }
814 (VertexAttributeValues::Unorm16x2(_), _) => {
815 panic!("Mismatched vertex attribute values")
816 }
817 (VertexAttributeValues::Sint16x4(this), VertexAttributeValues::Sint16x4(source)) => {
818 this.push(source[i]);
819 }
820 (VertexAttributeValues::Sint16x4(_), _) => panic!("Mismatched vertex attribute values"),
821 (VertexAttributeValues::Snorm16x4(this), VertexAttributeValues::Snorm16x4(source)) => {
822 this.push(source[i]);
823 }
824 (VertexAttributeValues::Snorm16x4(_), _) => {
825 panic!("Mismatched vertex attribute values")
826 }
827 (VertexAttributeValues::Uint16x4(this), VertexAttributeValues::Uint16x4(source)) => {
828 this.push(source[i]);
829 }
830 (VertexAttributeValues::Uint16x4(_), _) => panic!("Mismatched vertex attribute values"),
831 (VertexAttributeValues::Unorm16x4(this), VertexAttributeValues::Unorm16x4(source)) => {
832 this.push(source[i]);
833 }
834 (VertexAttributeValues::Unorm16x4(_), _) => {
835 panic!("Mismatched vertex attribute values")
836 }
837 (VertexAttributeValues::Sint8x2(this), VertexAttributeValues::Sint8x2(source)) => {
838 this.push(source[i]);
839 }
840 (VertexAttributeValues::Sint8x2(_), _) => panic!("Mismatched vertex attribute values"),
841 (VertexAttributeValues::Snorm8x2(this), VertexAttributeValues::Snorm8x2(source)) => {
842 this.push(source[i]);
843 }
844 (VertexAttributeValues::Snorm8x2(_), _) => panic!("Mismatched vertex attribute values"),
845 (VertexAttributeValues::Uint8x2(this), VertexAttributeValues::Uint8x2(source)) => {
846 this.push(source[i]);
847 }
848 (VertexAttributeValues::Uint8x2(_), _) => panic!("Mismatched vertex attribute values"),
849 (VertexAttributeValues::Unorm8x2(this), VertexAttributeValues::Unorm8x2(source)) => {
850 this.push(source[i]);
851 }
852 (VertexAttributeValues::Unorm8x2(_), _) => panic!("Mismatched vertex attribute values"),
853 (VertexAttributeValues::Sint8x4(this), VertexAttributeValues::Sint8x4(source)) => {
854 this.push(source[i]);
855 }
856 (VertexAttributeValues::Sint8x4(_), _) => panic!("Mismatched vertex attribute values"),
857 (VertexAttributeValues::Snorm8x4(this), VertexAttributeValues::Snorm8x4(source)) => {
858 this.push(source[i]);
859 }
860 (VertexAttributeValues::Snorm8x4(_), _) => panic!("Mismatched vertex attribute values"),
861 (VertexAttributeValues::Uint8x4(this), VertexAttributeValues::Uint8x4(source)) => {
862 this.push(source[i]);
863 }
864 (VertexAttributeValues::Uint8x4(_), _) => panic!("Mismatched vertex attribute values"),
865 (VertexAttributeValues::Unorm8x4(this), VertexAttributeValues::Unorm8x4(source)) => {
866 this.push(source[i]);
867 }
868 (VertexAttributeValues::Unorm8x4(_), _) => panic!("Mismatched vertex attribute values"),
869 (VertexAttributeValues::Uint8(this), VertexAttributeValues::Uint8(source)) => {
870 this.push(source[i]);
871 }
872 (VertexAttributeValues::Uint8(_), _) => panic!("Mismatched vertex attribute values"),
873 (VertexAttributeValues::Sint8(this), VertexAttributeValues::Sint8(source)) => {
874 this.push(source[i]);
875 }
876 (VertexAttributeValues::Sint8(_), _) => panic!("Mismatched vertex attribute values"),
877 (VertexAttributeValues::Unorm8(this), VertexAttributeValues::Unorm8(source)) => {
878 this.push(source[i]);
879 }
880 (VertexAttributeValues::Unorm8(_), _) => panic!("Mismatched vertex attribute values"),
881 (VertexAttributeValues::Snorm8(this), VertexAttributeValues::Snorm8(source)) => {
882 this.push(source[i]);
883 }
884 (VertexAttributeValues::Snorm8(_), _) => panic!("Mismatched vertex attribute values"),
885 (VertexAttributeValues::Uint16(this), VertexAttributeValues::Uint16(source)) => {
886 this.push(source[i]);
887 }
888 (VertexAttributeValues::Uint16(_), _) => panic!("Mismatched vertex attribute values"),
889 (VertexAttributeValues::Sint16(this), VertexAttributeValues::Sint16(source)) => {
890 this.push(source[i]);
891 }
892 (VertexAttributeValues::Sint16(_), _) => panic!("Mismatched vertex attribute values"),
893 (VertexAttributeValues::Unorm16(this), VertexAttributeValues::Unorm16(source)) => {
894 this.push(source[i]);
895 }
896 (VertexAttributeValues::Unorm16(_), _) => panic!("Mismatched vertex attribute values"),
897 (VertexAttributeValues::Snorm16(this), VertexAttributeValues::Snorm16(source)) => {
898 this.push(source[i]);
899 }
900 (VertexAttributeValues::Snorm16(_), _) => panic!("Mismatched vertex attribute values"),
901 (VertexAttributeValues::Float16(this), VertexAttributeValues::Float16(source)) => {
902 this.push(source[i]);
903 }
904 (VertexAttributeValues::Float16(_), _) => panic!("Mismatched vertex attribute values"),
905 (VertexAttributeValues::Float16x2(this), VertexAttributeValues::Float16x2(source)) => {
906 this.push(source[i]);
907 }
908 (VertexAttributeValues::Float16x2(_), _) => {
909 panic!("Mismatched vertex attribute values")
910 }
911 (VertexAttributeValues::Float16x4(this), VertexAttributeValues::Float16x4(source)) => {
912 this.push(source[i]);
913 }
914 (VertexAttributeValues::Float16x4(_), _) => {
915 panic!("Mismatched vertex attribute values")
916 }
917 (VertexAttributeValues::Float64(this), VertexAttributeValues::Float64(source)) => {
918 this.push(source[i]);
919 }
920 (VertexAttributeValues::Float64(_), _) => panic!("Mismatched vertex attribute values"),
921 (VertexAttributeValues::Float64x2(this), VertexAttributeValues::Float64x2(source)) => {
922 this.push(source[i]);
923 }
924 (VertexAttributeValues::Float64x2(_), _) => {
925 panic!("Mismatched vertex attribute values")
926 }
927 (VertexAttributeValues::Float64x3(this), VertexAttributeValues::Float64x3(source)) => {
928 this.push(source[i]);
929 }
930 (VertexAttributeValues::Float64x3(_), _) => {
931 panic!("Mismatched vertex attribute values")
932 }
933 (VertexAttributeValues::Float64x4(this), VertexAttributeValues::Float64x4(source)) => {
934 this.push(source[i]);
935 }
936 (VertexAttributeValues::Float64x4(_), _) => {
937 panic!("Mismatched vertex attribute values")
938 }
939 (
940 VertexAttributeValues::Unorm10_10_10_2(this),
941 VertexAttributeValues::Unorm10_10_10_2(source),
942 ) => {
943 this.push(source[i]);
944 }
945 (VertexAttributeValues::Unorm10_10_10_2(_), _) => {
946 panic!("Mismatched vertex attribute values")
947 }
948 (
949 VertexAttributeValues::Unorm8x4Bgra(this),
950 VertexAttributeValues::Unorm8x4Bgra(source),
951 ) => {
952 this.push(source[i]);
953 }
954 (VertexAttributeValues::Unorm8x4Bgra(_), _) => {
955 panic!("Mismatched vertex attribute values")
956 }
957 }
958 }
959
960 #[expect(
961 clippy::match_same_arms,
962 reason = "Although the `values` binding on some match arms may have matching types, each variant has different semantics; thus it's not guaranteed that they will use the same type forever."
963 )]
964 pub(crate) fn shrink_to_fit(&mut self) {
965 match self {
966 VertexAttributeValues::Float32(v) => v.shrink_to_fit(),
967 VertexAttributeValues::Sint32(v) => v.shrink_to_fit(),
968 VertexAttributeValues::Uint32(v) => v.shrink_to_fit(),
969 VertexAttributeValues::Float32x2(v) => v.shrink_to_fit(),
970 VertexAttributeValues::Sint32x2(v) => v.shrink_to_fit(),
971 VertexAttributeValues::Uint32x2(v) => v.shrink_to_fit(),
972 VertexAttributeValues::Float32x3(v) => v.shrink_to_fit(),
973 VertexAttributeValues::Sint32x3(v) => v.shrink_to_fit(),
974 VertexAttributeValues::Uint32x3(v) => v.shrink_to_fit(),
975 VertexAttributeValues::Float32x4(v) => v.shrink_to_fit(),
976 VertexAttributeValues::Sint32x4(v) => v.shrink_to_fit(),
977 VertexAttributeValues::Uint32x4(v) => v.shrink_to_fit(),
978 VertexAttributeValues::Sint16x2(v) => v.shrink_to_fit(),
979 VertexAttributeValues::Snorm16x2(v) => v.shrink_to_fit(),
980 VertexAttributeValues::Uint16x2(v) => v.shrink_to_fit(),
981 VertexAttributeValues::Unorm16x2(v) => v.shrink_to_fit(),
982 VertexAttributeValues::Sint16x4(v) => v.shrink_to_fit(),
983 VertexAttributeValues::Snorm16x4(v) => v.shrink_to_fit(),
984 VertexAttributeValues::Uint16x4(v) => v.shrink_to_fit(),
985 VertexAttributeValues::Unorm16x4(v) => v.shrink_to_fit(),
986 VertexAttributeValues::Sint8x2(v) => v.shrink_to_fit(),
987 VertexAttributeValues::Snorm8x2(v) => v.shrink_to_fit(),
988 VertexAttributeValues::Uint8x2(v) => v.shrink_to_fit(),
989 VertexAttributeValues::Unorm8x2(v) => v.shrink_to_fit(),
990 VertexAttributeValues::Sint8x4(v) => v.shrink_to_fit(),
991 VertexAttributeValues::Snorm8x4(v) => v.shrink_to_fit(),
992 VertexAttributeValues::Uint8x4(v) => v.shrink_to_fit(),
993 VertexAttributeValues::Unorm8x4(v) => v.shrink_to_fit(),
994 VertexAttributeValues::Uint8(v) => v.shrink_to_fit(),
995 VertexAttributeValues::Sint8(v) => v.shrink_to_fit(),
996 VertexAttributeValues::Unorm8(v) => v.shrink_to_fit(),
997 VertexAttributeValues::Snorm8(v) => v.shrink_to_fit(),
998 VertexAttributeValues::Uint16(v) => v.shrink_to_fit(),
999 VertexAttributeValues::Sint16(v) => v.shrink_to_fit(),
1000 VertexAttributeValues::Unorm16(v) => v.shrink_to_fit(),
1001 VertexAttributeValues::Snorm16(v) => v.shrink_to_fit(),
1002 VertexAttributeValues::Float16(v) => v.shrink_to_fit(),
1003 VertexAttributeValues::Float16x2(v) => v.shrink_to_fit(),
1004 VertexAttributeValues::Float16x4(v) => v.shrink_to_fit(),
1005 VertexAttributeValues::Float64(v) => v.shrink_to_fit(),
1006 VertexAttributeValues::Float64x2(v) => v.shrink_to_fit(),
1007 VertexAttributeValues::Float64x3(v) => v.shrink_to_fit(),
1008 VertexAttributeValues::Float64x4(v) => v.shrink_to_fit(),
1009 VertexAttributeValues::Unorm10_10_10_2(v) => v.shrink_to_fit(),
1010 VertexAttributeValues::Unorm8x4Bgra(v) => v.shrink_to_fit(),
1011 }
1012 }
1013}
1014
1015impl From<&VertexAttributeValues> for VertexFormat {
1016 fn from(values: &VertexAttributeValues) -> Self {
1017 match values {
1018 VertexAttributeValues::Float32(_) => VertexFormat::Float32,
1019 VertexAttributeValues::Sint32(_) => VertexFormat::Sint32,
1020 VertexAttributeValues::Uint32(_) => VertexFormat::Uint32,
1021 VertexAttributeValues::Float32x2(_) => VertexFormat::Float32x2,
1022 VertexAttributeValues::Sint32x2(_) => VertexFormat::Sint32x2,
1023 VertexAttributeValues::Uint32x2(_) => VertexFormat::Uint32x2,
1024 VertexAttributeValues::Float32x3(_) => VertexFormat::Float32x3,
1025 VertexAttributeValues::Sint32x3(_) => VertexFormat::Sint32x3,
1026 VertexAttributeValues::Uint32x3(_) => VertexFormat::Uint32x3,
1027 VertexAttributeValues::Float32x4(_) => VertexFormat::Float32x4,
1028 VertexAttributeValues::Sint32x4(_) => VertexFormat::Sint32x4,
1029 VertexAttributeValues::Uint32x4(_) => VertexFormat::Uint32x4,
1030 VertexAttributeValues::Sint16x2(_) => VertexFormat::Sint16x2,
1031 VertexAttributeValues::Snorm16x2(_) => VertexFormat::Snorm16x2,
1032 VertexAttributeValues::Uint16x2(_) => VertexFormat::Uint16x2,
1033 VertexAttributeValues::Unorm16x2(_) => VertexFormat::Unorm16x2,
1034 VertexAttributeValues::Sint16x4(_) => VertexFormat::Sint16x4,
1035 VertexAttributeValues::Snorm16x4(_) => VertexFormat::Snorm16x4,
1036 VertexAttributeValues::Uint16x4(_) => VertexFormat::Uint16x4,
1037 VertexAttributeValues::Unorm16x4(_) => VertexFormat::Unorm16x4,
1038 VertexAttributeValues::Sint8x2(_) => VertexFormat::Sint8x2,
1039 VertexAttributeValues::Snorm8x2(_) => VertexFormat::Snorm8x2,
1040 VertexAttributeValues::Uint8x2(_) => VertexFormat::Uint8x2,
1041 VertexAttributeValues::Unorm8x2(_) => VertexFormat::Unorm8x2,
1042 VertexAttributeValues::Sint8x4(_) => VertexFormat::Sint8x4,
1043 VertexAttributeValues::Snorm8x4(_) => VertexFormat::Snorm8x4,
1044 VertexAttributeValues::Uint8x4(_) => VertexFormat::Uint8x4,
1045 VertexAttributeValues::Unorm8x4(_) => VertexFormat::Unorm8x4,
1046 VertexAttributeValues::Uint8(_) => VertexFormat::Uint8,
1047 VertexAttributeValues::Sint8(_) => VertexFormat::Sint8,
1048 VertexAttributeValues::Unorm8(_) => VertexFormat::Unorm8,
1049 VertexAttributeValues::Snorm8(_) => VertexFormat::Snorm8,
1050 VertexAttributeValues::Uint16(_) => VertexFormat::Uint16,
1051 VertexAttributeValues::Sint16(_) => VertexFormat::Sint16,
1052 VertexAttributeValues::Unorm16(_) => VertexFormat::Unorm16,
1053 VertexAttributeValues::Snorm16(_) => VertexFormat::Snorm16,
1054 VertexAttributeValues::Float16(_) => VertexFormat::Float16,
1055 VertexAttributeValues::Float16x2(_) => VertexFormat::Float16x2,
1056 VertexAttributeValues::Float16x4(_) => VertexFormat::Float16x4,
1057 VertexAttributeValues::Float64(_) => VertexFormat::Float64,
1058 VertexAttributeValues::Float64x2(_) => VertexFormat::Float64x2,
1059 VertexAttributeValues::Float64x3(_) => VertexFormat::Float64x3,
1060 VertexAttributeValues::Float64x4(_) => VertexFormat::Float64x4,
1061 VertexAttributeValues::Unorm10_10_10_2(_) => VertexFormat::Unorm10_10_10_2,
1062 VertexAttributeValues::Unorm8x4Bgra(_) => VertexFormat::Unorm8x4Bgra,
1063 }
1064 }
1065}
1066
1067#[derive(Default, Clone, Debug, Hash, Eq, PartialEq)]
1069pub struct VertexBufferLayout {
1070 pub array_stride: BufferAddress,
1072 pub step_mode: VertexStepMode,
1074 pub attributes: Vec<VertexAttribute>,
1076}
1077
1078impl VertexBufferLayout {
1079 pub fn from_vertex_formats<T: IntoIterator<Item = VertexFormat>>(
1084 step_mode: VertexStepMode,
1085 vertex_formats: T,
1086 ) -> Self {
1087 let mut offset = 0;
1088 let mut attributes = Vec::new();
1089 for (shader_location, format) in vertex_formats.into_iter().enumerate() {
1090 attributes.push(VertexAttribute {
1091 format,
1092 offset,
1093 shader_location: shader_location as u32,
1094 });
1095 offset += format.size();
1096 }
1097
1098 VertexBufferLayout {
1099 array_stride: offset,
1100 step_mode,
1101 attributes,
1102 }
1103 }
1104
1105 pub fn offset_locations_by(mut self, location: u32) -> Self {
1108 self.attributes.iter_mut().for_each(|attr| {
1109 attr.shader_location += location;
1110 });
1111 self
1112 }
1113}
1114
1115#[derive(Clone, Debug)]
1125pub struct MeshVertexBufferLayoutRef(pub Arc<MeshVertexBufferLayout>);
1126
1127#[derive(Clone, Default, Resource)]
1129pub struct MeshVertexBufferLayouts(HashSet<Arc<MeshVertexBufferLayout>>);
1130
1131impl MeshVertexBufferLayouts {
1132 pub fn insert(&mut self, layout: MeshVertexBufferLayout) -> MeshVertexBufferLayoutRef {
1136 MeshVertexBufferLayoutRef(
1141 self.0
1142 .get_or_insert_with(&layout, |layout| Arc::new(layout.clone()))
1143 .clone(),
1144 )
1145 }
1146}
1147
1148impl PartialEq for MeshVertexBufferLayoutRef {
1149 fn eq(&self, other: &Self) -> bool {
1150 Arc::ptr_eq(&self.0, &other.0)
1151 }
1152}
1153
1154impl Eq for MeshVertexBufferLayoutRef {}
1155
1156impl Hash for MeshVertexBufferLayoutRef {
1157 fn hash<H: Hasher>(&self, state: &mut H) {
1158 (Arc::as_ptr(&self.0) as usize).hash(state);
1161 }
1162}
1163
1164pub(crate) fn arr_f32_to_unorm8<const N: usize>(value: [f32; N]) -> [u8; N] {
1165 value.map(|v| (v.clamp(0.0, 1.0) * u8::MAX as f32).round() as u8)
1166}
1167
1168pub(crate) fn arr_f32_to_snorm8<const N: usize>(value: [f32; N]) -> [i8; N] {
1169 value.map(|v| (v.clamp(-1.0, 1.0) * i8::MAX as f32).round() as i8)
1170}
1171
1172pub(crate) fn arr_f32_to_unorm16<const N: usize>(value: [f32; N]) -> [u16; N] {
1173 value.map(|v| (v.clamp(0.0, 1.0) * u16::MAX as f32).round() as u16)
1174}
1175
1176pub(crate) fn arr_f32_to_snorm16<const N: usize>(value: [f32; N]) -> [i16; N] {
1177 value.map(|v| (v.clamp(-1.0, 1.0) * i16::MAX as f32).round() as i16)
1178}
1179
1180pub(crate) fn arr_f32_to_float16<const N: usize>(value: [f32; N]) -> [half::f16; N] {
1181 value.map(half::f16::from_f32)
1182}
1183
1184pub fn octahedral_encode_signed(v: Vec3) -> Vec2 {
1186 let n = v / (v.x.abs() + v.y.abs() + v.z.abs());
1187 let octahedral_wrap = (1.0 - n.yx().abs())
1188 * Vec2::select(
1189 n.xy().cmpge(vec2(0.0, 0.0)),
1190 vec2(1.0, 1.0),
1191 vec2(-1.0, -1.0),
1192 );
1193 if n.z >= 0.0 {
1194 n.xy()
1195 } else {
1196 octahedral_wrap
1197 }
1198}
1199
1200pub fn octahedral_encode_tangent(v: Vec3, sign: f32) -> Vec2 {
1202 let bits = 16.;
1204 let bias = 1. / (bevy_math::ops::powf(2.0, bits - 1.) - 1.);
1205
1206 let mut n_xy = octahedral_encode_signed(v);
1207 n_xy.y = n_xy.y * 0.5 + 0.5;
1209 n_xy.y = n_xy.y.max(bias);
1210 n_xy.y *= sign.signum();
1212 n_xy
1213}
1214
1215pub fn octahedral_decode_signed(v: Vec2) -> Vec3 {
1217 let mut n = Vec3::new(v.x, v.y, 1.0 - v.x.abs() - v.y.abs());
1218 let t = (-n.z).clamp(0.0, 1.0);
1219 let w = Vec2::select(n.xy().cmpge(vec2(0.0, 0.0)), vec2(-t, -t), vec2(t, t));
1220 n = Vec3::new(n.x + w.x, n.y + w.y, n.z);
1221 n.normalize()
1222}
1223
1224pub fn octahedral_decode_tangent(v: Vec2) -> (Vec3, f32) {
1226 let sign = v.y.signum();
1227 let mut f = v;
1228 f.y = f.y.abs();
1229 f.y = f.y * 2.0 - 1.0;
1230 (octahedral_decode_signed(f), sign)
1231}
1232
1233#[cfg(test)]
1234mod tests {
1235 use bevy_math::{vec2, vec3, Vec4Swizzles};
1236
1237 use crate::{
1238 octahedral_decode_signed, octahedral_decode_tangent,
1239 vertex::{octahedral_encode_signed, octahedral_encode_tangent},
1240 };
1241
1242 #[test]
1243 fn octahedral_encode_decode() {
1244 let vectors = [
1245 vec3(1.0, 2.0, 3.0).normalize().extend(1.0),
1246 vec3(1.0, 0.0, 0.0).extend(-1.0),
1247 vec3(0.0, 1.0, 0.0).extend(-1.0),
1248 vec3(0.0, 0.0, -1.0).extend(1.0),
1249 vec3(0.0, 0.0, -1.0).extend(-1.0),
1250 ];
1251 let expected_encoded_normals = [
1252 vec2(0.16666667, 0.33333334),
1253 vec2(1.0, 0.0),
1254 vec2(0.0, 1.0),
1255 vec2(1.0, 1.0),
1256 vec2(1.0, 1.0),
1257 ];
1258 let expected_encoded_tangents = [
1259 vec2(0.16666667, 0.6666667),
1260 vec2(1.0, -0.5),
1261 vec2(0.0, -1.0),
1262 vec2(1.0, 1.0),
1263 vec2(1.0, -1.0),
1264 ];
1265 for (i, &v) in vectors.iter().enumerate() {
1266 let encoded_normal = octahedral_encode_signed(v.xyz());
1267 let decoded_normal = octahedral_decode_signed(encoded_normal);
1268 assert!(encoded_normal.distance(expected_encoded_normals[i]) < 1e-8);
1269 assert!(decoded_normal.distance(vectors[i].xyz()) < 1e-7);
1270
1271 let encoded_tangent = octahedral_encode_tangent(v.xyz(), v.w);
1272 let (decoded_tangent, decoded_sign) = octahedral_decode_tangent(encoded_tangent);
1273 assert!(encoded_tangent.distance(expected_encoded_tangents[i]) < 1e-8);
1274 assert_eq!(v.w, decoded_sign);
1275 assert!(decoded_tangent.distance(v.xyz()) < 1e-7);
1276 }
1277 }
1278}