pasture_algorithms/
bounds.rs1use anyhow::{Context, Result};
2use pasture_core::{
3 containers::{BorrowedBuffer, BorrowedBufferExt},
4 layout::attributes::POSITION_3D,
5 math::AABB,
6 nalgebra::{Point3, Vector3},
7};
8
9pub fn calculate_bounds<'a, T: BorrowedBuffer<'a>>(buffer: &'a T) -> Option<AABB<f64>> {
12 if buffer.len() == 0 {
13 return None;
14 }
15 let position_attribute = match buffer
16 .point_layout()
17 .get_attribute_by_name(POSITION_3D.name())
18 {
19 Some(a) => a,
20 None => return None,
21 };
22
23 if position_attribute.datatype() == POSITION_3D.datatype() {
24 Some(calculate_bounds_from_default_positions(buffer))
25 } else {
26 calculate_bounds_from_custom_positions(buffer).ok()
27 }
28}
29
30fn calculate_bounds_from_default_positions<'a, T: BorrowedBuffer<'a>>(buffer: &'a T) -> AABB<f64> {
31 let mut pos_min = Point3::new(f64::MAX, f64::MAX, f64::MAX);
32 let mut pos_max = Point3::new(f64::MIN, f64::MIN, f64::MIN);
33 for pos in buffer.view_attribute::<Vector3<f64>>(&POSITION_3D) {
34 if pos.x < pos_min.x {
35 pos_min.x = pos.x;
36 }
37 if pos.y < pos_min.y {
38 pos_min.y = pos.y;
39 }
40 if pos.z < pos_min.z {
41 pos_min.z = pos.z;
42 }
43 if pos.x > pos_max.x {
44 pos_max.x = pos.x;
45 }
46 if pos.y > pos_max.y {
47 pos_max.y = pos.y;
48 }
49 if pos.z > pos_max.z {
50 pos_max.z = pos.z;
51 }
52 }
53 AABB::from_min_max(pos_min, pos_max)
54}
55
56fn calculate_bounds_from_custom_positions<'a, T: BorrowedBuffer<'a>>(
57 buffer: &'a T,
58) -> Result<AABB<f64>> {
59 let mut pos_min = Point3::new(f64::MAX, f64::MAX, f64::MAX);
60 let mut pos_max = Point3::new(f64::MIN, f64::MIN, f64::MIN);
61 let attribute_view = buffer
62 .view_attribute_with_conversion::<Vector3<f64>>(&POSITION_3D)
63 .context("Can't convert POSITION_3D attribute to Vector3<f64>")?;
64 for pos in attribute_view {
65 if pos.x < pos_min.x {
66 pos_min.x = pos.x;
67 }
68 if pos.y < pos_min.y {
69 pos_min.y = pos.y;
70 }
71 if pos.z < pos_min.z {
72 pos_min.z = pos.z;
73 }
74 if pos.x > pos_max.x {
75 pos_max.x = pos.x;
76 }
77 if pos.y > pos_max.y {
78 pos_max.y = pos.y;
79 }
80 if pos.z > pos_max.z {
81 pos_max.z = pos.z;
82 }
83 }
84 Ok(AABB::from_min_max(pos_min, pos_max))
85}