enigma_3d/
geometry.rs

1use std::fmt::{Debug, Display, Formatter};
2use glium::{implement_uniform_block, 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}
11implement_uniform_block!(BoneTransforms, bone_transforms);
12
13#[derive(Copy, Clone)]
14pub struct InstanceAttribute {
15    pub model_matrix: [[f32; 4]; 4],
16}
17implement_vertex!(InstanceAttribute, model_matrix);
18
19#[derive(Copy, Clone, Serialize, Deserialize)]
20pub struct Vertex {
21    pub position: [f32; 3],
22    pub texcoord: [f32; 2],
23    pub color: [f32; 3],
24    pub normal: [f32; 3],
25    pub bone_indices: [u32; 4],
26    pub bone_weights: [f32; 4],
27}
28
29glium::implement_vertex!(Vertex, position, texcoord, color, normal, bone_indices, bone_weights);
30
31
32#[derive(Serialize, Deserialize)]
33pub struct BoundingBoxSerializer {
34    pub center: [f32; 3],
35    pub width: f32,
36    pub height: f32,
37    pub depth: f32,
38}
39
40#[derive(Copy, Clone)]
41pub struct BoundingBox {
42    pub center: Vector3<f32>,
43    //relative to the objects position
44    pub width: f32,
45    pub height: f32,
46    pub depth: f32,
47}
48
49#[derive(Serialize, Deserialize)]
50pub struct BoundingBoxMesh {
51    pub vertices: Vec<Vertex>,
52    pub indices: Vec<u32>,
53}
54
55impl Debug for Vertex {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        f.debug_struct("Vertex")
58            .field("position", &self.position)
59            .field("texcoord", &self.texcoord)
60            .field("color", &self.color)
61            .field("normal", &self.normal)
62            .field("bone_indices", &self.bone_indices)
63            .field("bone_weights", &self.bone_weights)
64            .finish()
65    }
66}
67
68impl Display for Vertex {
69    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
70        f.debug_struct("Vertex")
71            .field("position", &self.position)
72            .field("texcoord", &self.texcoord)
73            .field("color", &self.color)
74            .field("normal", &self.normal)
75            .field("bone_indices", &self.bone_indices)
76            .field("bone_weights", &self.bone_weights)
77            .finish()
78    }
79}
80
81impl BoundingBoxMesh {
82    pub fn new(bounding_box: &BoundingBox) -> Self {
83        let half_width = bounding_box.width / 2.0;
84        let half_height = bounding_box.height / 2.0;
85        let half_depth = bounding_box.depth / 2.0;
86
87        let corners = [
88            bounding_box.center + Vector3::new(-half_width, -half_height, -half_depth),
89            bounding_box.center + Vector3::new(half_width, -half_height, -half_depth),
90            bounding_box.center + Vector3::new(half_width, half_height, -half_depth),
91            bounding_box.center + Vector3::new(-half_width, half_height, -half_depth),
92            bounding_box.center + Vector3::new(-half_width, -half_height, half_depth),
93            bounding_box.center + Vector3::new(half_width, -half_height, half_depth),
94            bounding_box.center + Vector3::new(half_width, half_height, half_depth),
95            bounding_box.center + Vector3::new(-half_width, half_height, half_depth),
96        ];
97
98        let mut vertices = Vec::new();
99
100        for i in 0..corners.len() {
101            let corner = corners[i];
102            vertices.push(Vertex {
103                position: [corner.x, corner.y, corner.z],
104                texcoord: [0.0, 0.0],
105                color: [1.0, 1.0, 1.0],
106                normal: [0.0, 0.0, 0.0],
107                bone_indices: [0, 0, 0, 0],
108                bone_weights: [0.0, 0.0, 0.0, 0.0],
109            });
110        }
111        let indices = vec![
112            0, 1, 2, 2, 3, 0, // Front face
113            1, 5, 6, 6, 2, 1, // Right face
114            5, 4, 7, 7, 6, 5, // Back face
115            4, 0, 3, 3, 7, 4, // Left face
116            3, 2, 6, 6, 7, 3, // Top face
117            4, 5, 1, 1, 0, 4, // Bottom face
118        ];
119
120        Self {
121            vertices,
122            indices,
123        }
124    }
125}
126
127impl BoundingBox {
128    pub fn new(min_point: [f32; 3], max_point: [f32; 3]) -> Self {
129        let min = Vector3::from(min_point);
130        let max = Vector3::from(max_point);
131
132        // Calculate the center point
133        let center = (min + max) / 2.0;
134
135        // Calculate dimensions
136        let width = max.x - min.x;
137        let height = max.y - min.y;
138        let depth = max.z - min.z;
139
140        BoundingBox {
141            center,
142            width,
143            height,
144            depth,
145        }
146    }
147
148    // Returns the minimum point of the bounding box
149    pub fn min_point(&self) -> Vector3<f32> {
150        Vector3::new(
151            self.center.x - self.width / 2.0,
152            self.center.y - self.height / 2.0,
153            self.center.z - self.depth / 2.0,
154        )
155    }
156
157    // Returns the maximum point of the bounding box
158    pub fn max_point(&self) -> Vector3<f32> {
159        Vector3::new(
160            self.center.x + self.width / 2.0,
161            self.center.y + self.height / 2.0,
162            self.center.z + self.depth / 2.0,
163        )
164    }
165
166    pub fn to_serializer(&self) -> BoundingBoxSerializer {
167        BoundingBoxSerializer {
168            center: [self.center.x, self.center.y, self.center.z],
169            width: self.width,
170            height: self.height,
171            depth: self.depth,
172        }
173    }
174
175    pub fn from_serializer(serializer: BoundingBoxSerializer) -> Self {
176        Self {
177            center: Vector3::new(serializer.center[0], serializer.center[1], serializer.center[2]),
178            width: serializer.width,
179            height: serializer.height,
180            depth: serializer.depth,
181        }
182    }
183}