alice_sdf/types/
containers.rs1use crate::compiled::real::LawMinMax;
6use glam::Vec3;
7use serde::{Deserialize, Serialize};
8
9use super::SdfNode;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct SdfTree {
14 pub version: String,
16 pub root: SdfNode,
18 pub metadata: Option<SdfMetadata>,
20}
21
22impl SdfTree {
23 pub fn new(root: SdfNode) -> Self {
25 Self {
26 version: env!("CARGO_PKG_VERSION").to_string(),
27 root,
28 metadata: None,
29 }
30 }
31
32 pub fn with_metadata(root: SdfNode, metadata: SdfMetadata) -> Self {
34 Self {
35 version: env!("CARGO_PKG_VERSION").to_string(),
36 root,
37 metadata: Some(metadata),
38 }
39 }
40
41 pub fn node_count(&self) -> u32 {
43 self.root.node_count()
44 }
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, Default)]
49pub struct SdfMetadata {
50 pub name: Option<String>,
52 pub description: Option<String>,
54 pub author: Option<String>,
56 pub bounds: Option<(Vec3, Vec3)>,
58 pub custom: Option<std::collections::HashMap<String, String>>,
60}
61
62#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
64pub struct Aabb {
65 pub min: Vec3,
67 pub max: Vec3,
69}
70
71impl Aabb {
72 #[inline]
74 pub const fn new(min: Vec3, max: Vec3) -> Self {
75 Self { min, max }
76 }
77
78 #[inline]
81 pub const fn empty() -> Self {
82 Self {
83 min: Vec3::splat(f32::INFINITY),
84 max: Vec3::splat(f32::NEG_INFINITY),
85 }
86 }
87
88 #[inline]
90 pub fn expand_point(&mut self, point: Vec3) {
91 self.min = self.min.min(point);
92 self.max = self.max.max(point);
93 }
94
95 #[inline]
98 pub fn expand_aabb(&mut self, other: &Self) {
99 self.min = self.min.min(other.min);
100 self.max = self.max.max(other.max);
101 }
102
103 #[inline]
105 pub fn surface_area(&self) -> f32 {
106 let d = self.max - self.min;
107 2.0 * (d.x * d.y + d.y * d.z + d.z * d.x)
108 }
109
110 #[inline]
112 pub fn longest_axis(&self) -> usize {
113 let d = self.max - self.min;
114 if d.x > d.y && d.x > d.z {
115 0
116 } else if d.y > d.z {
117 1
118 } else {
119 2
120 }
121 }
122
123 #[inline]
125 pub fn signed_distance(&self, point: Vec3) -> f32 {
126 let q = (point - self.center()).abs() - (self.max - self.min) * 0.5;
127 q.max(Vec3::ZERO).length() + q.x.law_max(q.y.law_max(q.z)).law_min(0.0)
128 }
129
130 pub fn from_center_extents(center: Vec3, half_extents: Vec3) -> Self {
132 Self {
133 min: center - half_extents,
134 max: center + half_extents,
135 }
136 }
137
138 #[inline]
140 pub fn center(&self) -> Vec3 {
141 (self.min + self.max) * 0.5
142 }
143
144 pub fn size(&self) -> Vec3 {
146 self.max - self.min
147 }
148
149 pub fn half_extents(&self) -> Vec3 {
151 self.size() * 0.5
152 }
153
154 pub fn contains(&self, point: Vec3) -> bool {
156 point.x >= self.min.x
157 && point.x <= self.max.x
158 && point.y >= self.min.y
159 && point.y <= self.max.y
160 && point.z >= self.min.z
161 && point.z <= self.max.z
162 }
163
164 pub fn union(&self, other: &Self) -> Self {
166 Self {
167 min: self.min.min(other.min),
168 max: self.max.max(other.max),
169 }
170 }
171}
172
173#[derive(Debug, Clone, Copy)]
175pub struct Ray {
176 pub origin: Vec3,
178 pub direction: Vec3,
180}
181
182impl Ray {
183 pub fn new(origin: Vec3, direction: Vec3) -> Self {
185 Self {
186 origin,
187 direction: direction.normalize(),
188 }
189 }
190
191 pub fn at(&self, t: f32) -> Vec3 {
193 self.origin + self.direction * t
194 }
195}
196
197#[derive(Debug, Clone, Copy)]
199pub struct Hit {
200 pub distance: f32,
202 pub point: Vec3,
204 pub normal: Vec3,
206 pub steps: u32,
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn test_sdf_tree() {
216 let tree = SdfTree::new(SdfNode::sphere(1.0));
217 assert_eq!(tree.node_count(), 1);
218 }
219
220 #[test]
221 fn test_aabb() {
222 let aabb = Aabb::new(Vec3::new(-1.0, -1.0, -1.0), Vec3::new(1.0, 1.0, 1.0));
223 assert!(aabb.contains(Vec3::ZERO));
224 assert!(!aabb.contains(Vec3::new(2.0, 0.0, 0.0)));
225 }
226}