bvh.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // ┏┓ ╻ ╻╻ ╻
  2. // ┣┻┓┃┏┛┣━┫
  3. // ┗━┛┗┛ ╹ ╹
  4. use crate::geometry::Vec3;
  5. use crate::geometry::Axis;
  6. use crate::geometry::Ray;
  7. use crate::mesh::Face;
  8. use crate::mesh::Mesh;
  9. pub struct Intersection<'a> {
  10. pub t: f32,
  11. pub fr: FaceReference<'a>
  12. }
  13. impl PartialOrd for Intersection<'_> {
  14. fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
  15. return self.t.partial_cmp(&other.t);
  16. }
  17. }
  18. impl PartialEq for Intersection<'_> {
  19. fn eq(&self, other: &Self) -> bool {
  20. self.t == other.t
  21. }
  22. }
  23. /**
  24. * Axis-Aligned Bounding Box.
  25. */
  26. pub struct AABB {
  27. pub min: Vec3,
  28. pub max: Vec3
  29. }
  30. fn f32_min(a: f32, b: f32) -> f32 {
  31. return if a < b { a } else { b };
  32. }
  33. fn f32_max(a: f32, b: f32) -> f32 {
  34. return if a >= b { a } else { b };
  35. }
  36. impl AABB {
  37. pub fn extend(&mut self, m: &Mesh, f: &Face) {
  38. let coords = m.face_coords(f);
  39. self.min.x = f32::min(self.min.x, coords.iter().map(|c| c.x).reduce(f32_min).unwrap());
  40. self.min.y = f32::min(self.min.y, coords.iter().map(|c| c.y).reduce(f32_min).unwrap());
  41. self.min.z = f32::min(self.min.z, coords.iter().map(|c| c.z).reduce(f32_min).unwrap());
  42. self.max.x = f32::max(self.max.x, coords.iter().map(|c| c.x).reduce(f32_max).unwrap());
  43. self.max.y = f32::max(self.max.y, coords.iter().map(|c| c.y).reduce(f32_max).unwrap());
  44. self.max.z = f32::max(self.max.z, coords.iter().map(|c| c.z).reduce(f32_max).unwrap());
  45. }
  46. pub fn from(fr: &[FaceReference]) -> AABB {
  47. let mut aabb = AABB {
  48. min: Vec3::new(f32::INFINITY, f32::INFINITY, f32::INFINITY),
  49. max: Vec3::new(-f32::INFINITY, -f32::INFINITY, -f32::INFINITY),
  50. };
  51. for face_reference in fr {
  52. aabb.extend(face_reference.m, face_reference.f);
  53. }
  54. return aabb;
  55. }
  56. /**
  57. * Test for intersection of ABB with Ray r.
  58. * t is the maximum distance of the ray from its origin
  59. */
  60. pub fn intersect(&self, r: &Ray, t: f32) -> bool {
  61. // See [Tavian Barnes' site](https://tavianator.com/2011/ray_box.html) for details.
  62. let tx1 = (self.min.x - r.origin.x) * r.n_inv.x;
  63. let tx2 = (self.max.x - r.origin.x) * r.n_inv.x;
  64. let mut tmin = f32::min(tx1, tx2);
  65. let mut tmax = f32::max(tx1, tx2);
  66. let ty1 = (self.min.y - r.origin.y) * r.n_inv.y;
  67. let ty2 = (self.max.y - r.origin.y) * r.n_inv.y;
  68. tmin = f32::max(tmin, f32::min(ty1, ty2));
  69. tmax = f32::min(tmax, f32::max(ty1, ty2));
  70. let tz1 = (self.min.z - r.origin.z) * r.n_inv.z;
  71. let tz2 = (self.max.z - r.origin.z) * r.n_inv.z;
  72. tmin = f32::max(tmin, f32::min(tz1, tz2));
  73. tmax = f32::min(tmax, f32::max(tz1, tz2));
  74. return tmax >= f32::max(0.0, tmin) && tmin < t;
  75. }
  76. }
  77. /**
  78. * Bounding Volume Hierarchy
  79. */
  80. pub enum BVH<'a> {
  81. Node(AABB, Box<BVH<'a>>, Box<BVH<'a>>),
  82. Leaf(AABB, Vec<FaceReference<'a>>)
  83. }
  84. #[derive(Copy, Clone)]
  85. pub struct FaceReference<'a> {
  86. m: &'a Mesh,
  87. f: &'a Face
  88. }
  89. impl BVH<'_> {
  90. fn build_recursive<'a, 'b>(frs: &'b mut [FaceReference<'a>], recursion_limit: u16, split_axis: Axis) -> BVH<'a> {
  91. let aabb = AABB::from(frs);
  92. let frs_count = frs.len();
  93. if recursion_limit == 0 || frs_count <= 3 {
  94. // We have reached the maximum of recursions necessary.
  95. return BVH::Leaf(aabb, Vec::from(frs));
  96. }
  97. // Sort along the current axis
  98. frs.sort_by(|a,b| a.f.center.select(split_axis).partial_cmp(
  99. &b.f.center.select(split_axis)).unwrap());
  100. // Select using surface area heuristic
  101. let total_surface: f32= frs.iter().map(|fr| fr.f.area).sum();
  102. let mut split_index : usize = 0;
  103. let mut surface_area = 0.0;
  104. while surface_area < total_surface / 2.0 {
  105. surface_area += frs[split_index].f.area;
  106. split_index += 1;
  107. }
  108. // Recurse
  109. let (frs1, frs2) = frs.split_at_mut(split_index);
  110. let left = Self::build_recursive(frs1, recursion_limit - 1, split_axis.next());
  111. let right = Self::build_recursive(frs2, recursion_limit - 1, split_axis.next());
  112. return BVH::Node(aabb, Box::new(left), Box::new(right));
  113. }
  114. pub fn from<'a>(meshes: &'a Vec<Mesh>, recursion_depth: u16) -> BVH {
  115. // Create references for each triangle
  116. let mut references = vec!();
  117. for m in meshes {
  118. for f in &m.faces {
  119. references.push(FaceReference {
  120. m: &m,
  121. f: &f
  122. });
  123. }
  124. }
  125. let bvh = Self::build_recursive(&mut references, recursion_depth, Axis::x);
  126. return bvh;
  127. }
  128. fn intersect_ray_triangle<'a>(ray: &Ray, fr: &'a FaceReference) -> Option<Intersection<'a>> {
  129. // See Akenine-Möller et al. Real-Time Rendering (2018), 22.8 Ray/Triangle Intersection
  130. let p = fr.m.face_coords(fr.f);
  131. let e1 = p[1] - p[0];
  132. let e2 = p[2] - p[0];
  133. let q = ray.direction.cross(e2);
  134. let a = e1 * q;
  135. if f32::abs(a) < 1e-9 {
  136. return None;
  137. }
  138. let f = 1.0 / a;
  139. let s = &ray.origin - p[0];
  140. let u = f * (s * q);
  141. if u < 0.0 {
  142. return None
  143. };
  144. let r = s.cross(e1);
  145. let v = f * (ray.direction * r);
  146. if v < 0.0 || u + v > 1.0 {
  147. return None;
  148. }
  149. let t = f * (e2 * r);
  150. return Some(Intersection {
  151. t: t,
  152. fr: *fr
  153. });
  154. }
  155. pub fn intersect<'a>(&'a self, r : &Ray, counter: usize) -> (usize, Option<Intersection<'a>>) {
  156. match self {
  157. BVH::Leaf(aabb, frs) => {
  158. // Early-out if the ray does not intersect the AABB
  159. if !aabb.intersect(r, f32::INFINITY) {
  160. return (counter+1, None);
  161. }
  162. // Make intersection tests with individual triangles
  163. let closest_intersection : Option<Intersection> = frs.iter()
  164. .map(|fr| Self::intersect_ray_triangle(r, fr))
  165. .filter(|i| i.is_some())
  166. .map(|i| i.unwrap())
  167. .filter(|i| i.t >= 0.0)
  168. .reduce(|a, b| if a < b { a } else { b});
  169. return (counter+1, closest_intersection);
  170. },
  171. BVH::Node(aabb, left, right) => {
  172. // Early-out if the ray does not intersect the AABB
  173. if !aabb.intersect(r, f32::INFINITY) {
  174. return (counter + 1, None);
  175. }
  176. // Recurse down the tree
  177. let (c1, left_intersection) = left.intersect(r, counter + 1);
  178. let (c2, right_intersection) = right.intersect(r, counter + 1);
  179. if left_intersection.is_some() && right_intersection.is_some() {
  180. let (li, ri) = (left_intersection.unwrap(), right_intersection.unwrap());
  181. return if li < ri { (c1 + c2, Some(li)) } else {(c1 + c2, Some(ri))};
  182. } else {
  183. // At least one intersection is None.
  184. return (c1+c2, left_intersection.or(right_intersection));
  185. }
  186. }
  187. }
  188. }
  189. }
  190. impl std::fmt::Display for AABB {
  191. fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  192. return write!(f, "{} -> {}", self.min, self.max);
  193. }
  194. }
  195. impl std::fmt::Display for BVH<'_> {
  196. fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  197. match self {
  198. BVH::Leaf(aabb,_) => {
  199. return write!(f, "(Leaf {})", aabb);
  200. }
  201. BVH::Node(aabb, left, right) => {
  202. return write!(f, "(Node {}; {} {})", aabb, left, right);
  203. }
  204. }
  205. }
  206. }