cgv
Loading...
Searching...
No Matches
intersection.h
1#pragma once
2
3#include <cgv/media/axis_aligned_box.h>
4#include <limits>
5
6namespace cgv {
7 namespace media {
8 template <typename T>
9 bool update_range(T lb, T ub, T o, T d, unsigned i, unsigned& i_min, unsigned& i_max, T& t_min, T& t_max, T epsilon) {
10 // check for case where ray component is parallel to plane slab
11 if (std::abs(d) < epsilon)
12 return o >= lb && o <= ub;
13 // compute intersections
14 T f = T(1) / d;
15 T t0 = f * (lb - o);
16 T t1 = f * (ub - o);
17 if (t0 > t1)
18 std::swap(t0, t1);
19
20 // update interval
21 if (t0 > t_min) {
22 i_min = i;
23 t_min = t0;
24 }
25 if (t1 < t_max) {
26 i_max = i;
27 t_max = t1;
28 }
29 return true;
30 }
31
32 template <typename T, cgv::type::uint32_type N>
33 bool ray_axis_aligned_box_intersection(
34 const cgv::math::fvec<T,N>& origin, const cgv::math::fvec<T,N>& direction, const axis_aligned_box<T, N>& aabb,
35 T& t_result, cgv::math::fvec<T, N>& p_result, cgv::math::fvec<T, N>& n_result,
36 T epsilon) {
37
38 const cgv::math::fvec<T, N>& lb = aabb.get_min_pnt();
39 const cgv::math::fvec<T, N>& ub = aabb.get_max_pnt();
40
41 T t_min = -std::numeric_limits<T>::max();
42 T t_max = std::numeric_limits<T>::max();
43
44 unsigned i_min, i_max;
45 for (unsigned i = 0; i < N; ++i)
46 if (!update_range(lb[i], ub[i], origin[i], direction[i], i, i_min, i_max, t_min, t_max, epsilon))
47 return false;
48
49 if (t_max < 0 || t_min > t_max)
50 return false;
51
52 if (t_min < T(0)) {
53 t_result = t_max;
54 i_min = i_max;
55 }
56 else
57 t_result = t_min;
58
59 p_result = origin + t_result * direction;
60
61 n_result.zeros();
62 n_result[i_min] = direction[i_min] > T(0) ? T(-1) : T(1);
63
64 return true;
65 }
66 }
67}
A vector with zero based index.
Definition fvec.h:26
void zeros()
fill the vector with zeros
Definition fvec.h:133
the cgv namespace
Definition print.h:11