1use std::fmt::{Debug, Display, Formatter};
2use glium::implement_vertex;
3use nalgebra::Vector3;
4use serde::{Deserialize, Serialize};
5
6#[repr(C, align(16))]
7#[derive(Copy, Clone)]
8pub struct BoneTransforms {
9 pub bone_transforms: [[[f32; 4]; 4]; 128]
10}
11impl glium::uniforms::UniformBlock for BoneTransforms {
12 fn matches(_layout: &glium::program::BlockLayout, _base_offset: usize) -> Result<(), glium::uniforms::LayoutMismatchError> {
13 Ok(())
14 }
15 fn build_layout(base_offset: usize) -> glium::program::BlockLayout {
16 glium::program::BlockLayout::Struct {
17 members: vec![
18 ("bone_transforms".to_owned(), glium::program::BlockLayout::Array {
19 content: Box::new(glium::program::BlockLayout::BasicType {
20 ty: glium::uniforms::UniformType::FloatMat4,
21 offset_in_buffer: base_offset,
22 }),
23 length: 128,
24 }),
25 ],
26 }
27 }
28}
29
30#[derive(Copy, Clone)]
31pub struct InstanceAttribute {
32 pub model_matrix: [[f32; 4]; 4],
33}
34implement_vertex!(InstanceAttribute, model_matrix);
35
36#[derive(Copy, Clone, Serialize, Deserialize)]
37pub struct Vertex {
38 pub position: [f32; 3],
39 pub texcoord: [f32; 2],
40 pub color: [f32; 3],
41 pub normal: [f32; 3],
42 pub bone_indices: [u32; 4],
43 pub bone_weights: [f32; 4],
44}
45
46glium::implement_vertex!(Vertex, position, texcoord, color, normal, bone_indices, bone_weights);
47
48
49#[derive(Serialize, Deserialize)]
50pub struct BoundingBoxSerializer {
51 pub center: [f32; 3],
52 pub width: f32,
53 pub height: f32,
54 pub depth: f32,
55}
56
57#[derive(Copy, Clone)]
58pub struct BoundingBox {
59 pub center: Vector3<f32>,
60 pub width: f32,
62 pub height: f32,
63 pub depth: f32,
64}
65
66#[derive(Serialize, Deserialize)]
67pub struct BoundingBoxMesh {
68 pub vertices: Vec<Vertex>,
69 pub indices: Vec<u32>,
70}
71
72impl Debug for Vertex {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 f.debug_struct("Vertex")
75 .field("position", &self.position)
76 .field("texcoord", &self.texcoord)
77 .field("color", &self.color)
78 .field("normal", &self.normal)
79 .field("bone_indices", &self.bone_indices)
80 .field("bone_weights", &self.bone_weights)
81 .finish()
82 }
83}
84
85impl Display for Vertex {
86 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
87 f.debug_struct("Vertex")
88 .field("position", &self.position)
89 .field("texcoord", &self.texcoord)
90 .field("color", &self.color)
91 .field("normal", &self.normal)
92 .field("bone_indices", &self.bone_indices)
93 .field("bone_weights", &self.bone_weights)
94 .finish()
95 }
96}
97
98impl BoundingBoxMesh {
99 pub fn new(bounding_box: &BoundingBox) -> Self {
100 let half_width = bounding_box.width / 2.0;
101 let half_height = bounding_box.height / 2.0;
102 let half_depth = bounding_box.depth / 2.0;
103
104 let corners = [
105 bounding_box.center + Vector3::new(-half_width, -half_height, -half_depth),
106 bounding_box.center + Vector3::new(half_width, -half_height, -half_depth),
107 bounding_box.center + Vector3::new(half_width, half_height, -half_depth),
108 bounding_box.center + Vector3::new(-half_width, half_height, -half_depth),
109 bounding_box.center + Vector3::new(-half_width, -half_height, half_depth),
110 bounding_box.center + Vector3::new(half_width, -half_height, half_depth),
111 bounding_box.center + Vector3::new(half_width, half_height, half_depth),
112 bounding_box.center + Vector3::new(-half_width, half_height, half_depth),
113 ];
114
115 let mut vertices = Vec::new();
116
117 for i in 0..corners.len() {
118 let corner = corners[i];
119 vertices.push(Vertex {
120 position: [corner.x, corner.y, corner.z],
121 texcoord: [0.0, 0.0],
122 color: [1.0, 1.0, 1.0],
123 normal: [0.0, 0.0, 0.0],
124 bone_indices: [0, 0, 0, 0],
125 bone_weights: [0.0, 0.0, 0.0, 0.0],
126 });
127 }
128 let indices = vec![
129 0, 1, 2, 2, 3, 0, 1, 5, 6, 6, 2, 1, 5, 4, 7, 7, 6, 5, 4, 0, 3, 3, 7, 4, 3, 2, 6, 6, 7, 3, 4, 5, 1, 1, 0, 4, ];
136
137 Self {
138 vertices,
139 indices,
140 }
141 }
142}
143
144impl BoundingBox {
145 pub fn new(min_point: [f32; 3], max_point: [f32; 3]) -> Self {
146 let min = Vector3::from(min_point);
147 let max = Vector3::from(max_point);
148
149 let center = (min + max) / 2.0;
151
152 let width = max.x - min.x;
154 let height = max.y - min.y;
155 let depth = max.z - min.z;
156
157 BoundingBox {
158 center,
159 width,
160 height,
161 depth,
162 }
163 }
164
165 pub fn min_point(&self) -> Vector3<f32> {
167 Vector3::new(
168 self.center.x - self.width / 2.0,
169 self.center.y - self.height / 2.0,
170 self.center.z - self.depth / 2.0,
171 )
172 }
173
174 pub fn max_point(&self) -> Vector3<f32> {
176 Vector3::new(
177 self.center.x + self.width / 2.0,
178 self.center.y + self.height / 2.0,
179 self.center.z + self.depth / 2.0,
180 )
181 }
182
183 pub fn to_serializer(&self) -> BoundingBoxSerializer {
184 BoundingBoxSerializer {
185 center: [self.center.x, self.center.y, self.center.z],
186 width: self.width,
187 height: self.height,
188 depth: self.depth,
189 }
190 }
191
192 pub fn from_serializer(serializer: BoundingBoxSerializer) -> Self {
193 Self {
194 center: Vector3::new(serializer.center[0], serializer.center[1], serializer.center[2]),
195 width: serializer.width,
196 height: serializer.height,
197 depth: serializer.depth,
198 }
199 }
200}