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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use crate::{quantize_half, quantize_snorm};
use float_cmp::ApproxEqUlps;
pub trait DecodePosition {
fn decode_position(&self) -> [f32; 3];
}
pub trait FromVertex {
fn from_vertex(&mut self, vertex: &Vertex);
}
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
#[repr(C)]
pub struct PackedVertex {
pub p: [u16; 4],
pub n: [i8; 4],
pub t: [u16; 2],
}
impl FromVertex for PackedVertex {
fn from_vertex(&mut self, vertex: &Vertex) {
self.p[0] = quantize_half(vertex.p[0]) as u16;
self.p[1] = quantize_half(vertex.p[1]) as u16;
self.p[2] = quantize_half(vertex.p[2]) as u16;
self.p[3] = 0u16;
self.n[0] = quantize_snorm(vertex.n[0], 8) as i8;
self.n[1] = quantize_snorm(vertex.n[1], 8) as i8;
self.n[2] = quantize_snorm(vertex.n[2], 8) as i8;
self.n[3] = 0i8;
self.t[0] = quantize_half(vertex.t[0]) as u16;
self.t[1] = quantize_half(vertex.t[1]) as u16;
}
}
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
#[repr(C)]
pub struct PackedVertexOct {
pub p: [u16; 3],
pub n: [u8; 2],
pub t: [u16; 2],
}
impl FromVertex for PackedVertexOct {
fn from_vertex(&mut self, vertex: &Vertex) {
self.p[0] = quantize_half(vertex.p[0]) as u16;
self.p[1] = quantize_half(vertex.p[1]) as u16;
self.p[2] = quantize_half(vertex.p[2]) as u16;
let nsum = vertex.n[0].abs() + vertex.n[1].abs() + vertex.n[2].abs();
let nx = vertex.n[0] / nsum;
let ny = vertex.n[1] / nsum;
let nz = vertex.n[2];
let nu = if nz >= 0f32 {
nx
} else {
(1f32 - ny.abs()) * if nx >= 0f32 { 1f32 } else { -1f32 }
};
let nv = if nz >= 0f32 {
ny
} else {
(1f32 - nx.abs()) * if ny >= 0f32 { 1f32 } else { -1f32 }
};
self.n[0] = quantize_snorm(nu, 8) as u8;
self.n[1] = quantize_snorm(nv, 8) as u8;
self.t[0] = quantize_half(vertex.t[0]) as u16;
self.t[1] = quantize_half(vertex.t[1]) as u16;
}
}
#[derive(Default, Debug, Copy, Clone, PartialOrd)]
#[repr(C)]
pub struct Vertex {
pub p: [f32; 3],
pub n: [f32; 3],
pub t: [f32; 2],
}
impl PartialEq for Vertex {
fn eq(&self, other: &Vertex) -> bool {
self.p[0].approx_eq_ulps(&other.p[0], 2)
&& self.p[1].approx_eq_ulps(&other.p[1], 2)
&& self.p[2].approx_eq_ulps(&other.p[2], 2)
&& self.n[0].approx_eq_ulps(&other.n[0], 2)
&& self.n[1].approx_eq_ulps(&other.n[1], 2)
&& self.n[2].approx_eq_ulps(&other.n[2], 2)
&& self.t[0].approx_eq_ulps(&other.t[0], 2)
&& self.t[1].approx_eq_ulps(&other.t[1], 2)
}
}
impl Eq for Vertex {}
impl Vertex {}
impl DecodePosition for Vertex {
fn decode_position(&self) -> [f32; 3] {
self.p
}
}
pub fn pack_vertices<T: FromVertex + Default + Clone>(input: &[Vertex]) -> Vec<T> {
let mut vertices: Vec<T> = vec![T::default(); input.len()];
for i in 0..input.len() {
vertices[i].from_vertex(&input[i]);
}
vertices
}