Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | // | ||
4 | /// @file Ray.h | ||
5 | /// | ||
6 | /// @author Ken Museth | ||
7 | /// | ||
8 | /// @brief A Ray class. | ||
9 | |||
10 | #ifndef OPENVDB_MATH_RAY_HAS_BEEN_INCLUDED | ||
11 | #define OPENVDB_MATH_RAY_HAS_BEEN_INCLUDED | ||
12 | |||
13 | #include "Math.h" | ||
14 | #include "Vec3.h" | ||
15 | #include "Transform.h" | ||
16 | #include <algorithm> // for std::swap() | ||
17 | #include <iostream> // for std::ostream | ||
18 | #include <limits> // for std::numeric_limits<Type>::max() | ||
19 | |||
20 | namespace openvdb { | ||
21 | OPENVDB_USE_VERSION_NAMESPACE | ||
22 | namespace OPENVDB_VERSION_NAME { | ||
23 | namespace math { | ||
24 | |||
25 | template<typename RealT = double> | ||
26 | class Ray | ||
27 | { | ||
28 | public: | ||
29 | static_assert(std::is_floating_point<RealT>::value, | ||
30 | "math::Ray requires a floating-point value type"); | ||
31 | |||
32 | using RealType = RealT; | ||
33 | using Vec3Type = Vec3<RealT>; | ||
34 | using Vec3T = Vec3Type; | ||
35 | |||
36 | struct TimeSpan { | ||
37 | RealT t0, t1; | ||
38 | /// @brief Default constructor | ||
39 | TimeSpan() {} | ||
40 | /// @brief Constructor | ||
41 |
20/30✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✓ Branch 27 taken 1048576 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
|
1048761 | TimeSpan(RealT _t0, RealT _t1) : t0(_t0), t1(_t1) {} |
42 | /// @brief Set both times | ||
43 | 1319509 | inline void set(RealT _t0, RealT _t1) { t0=_t0; t1=_t1; } | |
44 | /// @brief Get both times | ||
45 | 1048625 | inline void get(RealT& _t0, RealT& _t1) const { _t0=t0; _t1=t1; } | |
46 | /// @brief Return @c true if t1 is larger than t0 by at least eps. | ||
47 |
29/68✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 14 times.
✓ Branch 19 taken 8 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 1 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 1 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 1 times.
✗ Branch 48 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 51 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 53 taken 1 times.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 57 taken 1 times.
✗ Branch 58 not taken.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✓ Branch 63 taken 1 times.
✗ Branch 64 not taken.
✓ Branch 65 taken 1 times.
✗ Branch 66 not taken.
✓ Branch 67 taken 1 times.
|
63 | inline bool valid(RealT eps=math::Delta<RealT>::value()) const { return (t1-t0)>eps; } |
48 | /// @brief Return the midpoint of the ray. | ||
49 | 2 | inline RealT mid() const { return 0.5*(t0 + t1); } | |
50 | /// @brief Multiplies both times | ||
51 | inline void scale(RealT s) {assert(s>0); t0*=s; t1*=s; } | ||
52 | /// @brief Return @c true if time is inclusive | ||
53 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | inline bool test(RealT t) const { return (t>=t0 && t<=t1); } |
54 | }; | ||
55 | |||
56 | 131 | Ray(const Vec3Type& eye = Vec3Type(0,0,0), | |
57 | const Vec3Type& direction = Vec3Type(1,0,0), | ||
58 | RealT t0 = math::Delta<RealT>::value(), | ||
59 | RealT t1 = std::numeric_limits<RealT>::max()) | ||
60 |
19/27✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✓ Branch 27 taken 1048576 times.
✗ Branch 28 not taken.
|
1048760 | : mEye(eye), mDir(direction), mInvDir(1/mDir), mTimeSpan(t0, t1) |
61 | { | ||
62 | } | ||
63 | |||
64 |
5/28✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1082366 times.
|
1082381 | inline void setEye(const Vec3Type& eye) { mEye = eye; } |
65 | |||
66 | inline void setDir(const Vec3Type& dir) | ||
67 | { | ||
68 |
5/28✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1082366 times.
|
1082381 | mDir = dir; |
69 |
5/28✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1082366 times.
|
1082381 | mInvDir = 1/mDir; |
70 | } | ||
71 | |||
72 |
5/28✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 3 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1082366 times.
|
1082379 | inline void setMinTime(RealT t0) { assert(t0>0); mTimeSpan.t0 = t0; } |
73 | |||
74 |
5/28✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 6 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 3 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✗ Branch 52 not taken.
✓ Branch 53 taken 1082366 times.
|
1082379 | inline void setMaxTime(RealT t1) { assert(t1>0); mTimeSpan.t1 = t1; } |
75 | |||
76 | inline void setTimes( | ||
77 | RealT t0 = math::Delta<RealT>::value(), | ||
78 | RealT t1 = std::numeric_limits<RealT>::max()) | ||
79 | { | ||
80 |
14/32✓ Branch 0 taken 537345 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 537345 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✓ Branch 10 taken 515868 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 515868 times.
✓ Branch 15 taken 21 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 21 times.
✓ Branch 20 taken 266257 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 266257 times.
✓ Branch 25 taken 6 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 6 times.
✓ Branch 30 taken 13 times.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✓ Branch 33 taken 13 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
|
1319516 | assert(t0>0 && t1>0); |
81 | mTimeSpan.set(t0, t1); | ||
82 | 13 | } | |
83 | |||
84 | inline void scaleTimes(RealT scale) { mTimeSpan.scale(scale); } | ||
85 | |||
86 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | inline void reset( |
87 | const Vec3Type& eye, | ||
88 | const Vec3Type& direction, | ||
89 | RealT t0 = math::Delta<RealT>::value(), | ||
90 | RealT t1 = std::numeric_limits<RealT>::max()) | ||
91 | { | ||
92 | this->setEye(eye); | ||
93 | this->setDir(direction); | ||
94 | this->setTimes(t0, t1); | ||
95 | 2 | } | |
96 | |||
97 | inline const Vec3T& eye() const {return mEye;} | ||
98 | |||
99 |
2/4✓ Branch 1 taken 205861 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
205869 | inline const Vec3T& dir() const {return mDir;} |
100 | |||
101 | inline const Vec3T& invDir() const {return mInvDir;} | ||
102 | |||
103 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2668165 | inline RealT t0() const {return mTimeSpan.t0;} |
104 | |||
105 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2668178 | inline RealT t1() const {return mTimeSpan.t1;} |
106 | |||
107 | /// @brief Return the position along the ray at the specified time. | ||
108 | 5014770 | inline Vec3R operator()(RealT time) const { return mEye + mDir * time; } | |
109 | |||
110 | /// @brief Return the starting point of the ray. | ||
111 | 3 | inline Vec3R start() const { return (*this)(mTimeSpan.t0); } | |
112 | |||
113 | /// @brief Return the endpoint of the ray. | ||
114 | 3 | inline Vec3R end() const { return (*this)(mTimeSpan.t1); } | |
115 | |||
116 | /// @brief Return the midpoint of the ray. | ||
117 | 3 | inline Vec3R mid() const { return (*this)(mTimeSpan.mid()); } | |
118 | |||
119 | /// @brief Return @c true if t1 is larger than t0 by at least eps. | ||
120 | inline bool valid(RealT eps=math::Delta<float>::value()) const { return mTimeSpan.valid(eps); } | ||
121 | |||
122 | /// @brief Return @c true if @a time is within t0 and t1, both inclusive. | ||
123 | inline bool test(RealT time) const { return mTimeSpan.test(time); } | ||
124 | |||
125 | /// @brief Return a new Ray that is transformed with the specified map. | ||
126 | /// @param map the map from which to construct the new Ray. | ||
127 | /// @warning Assumes a linear map and a normalized direction. | ||
128 | /// @details The requirement that the direction is normalized | ||
129 | /// follows from the transformation of t0 and t1 - and that fact that | ||
130 | /// we want applyMap and applyInverseMap to be inverse operations. | ||
131 | template<typename MapType> | ||
132 | 2 | inline Ray applyMap(const MapType& map) const | |
133 | { | ||
134 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | assert(map.isLinear()); |
135 | ✗ | assert(math::isRelOrApproxEqual(mDir.length(), RealT(1), | |
136 | Tolerance<RealT>::value(), Delta<RealT>::value())); | ||
137 | 2 | const Vec3T eye = map.applyMap(mEye); | |
138 | 2 | const Vec3T dir = map.applyJacobian(mDir); | |
139 | const RealT length = dir.length(); | ||
140 | 2 | return Ray(eye, dir/length, length*mTimeSpan.t0, length*mTimeSpan.t1); | |
141 | } | ||
142 | |||
143 | /// @brief Return a new Ray that is transformed with the inverse of the specified map. | ||
144 | /// @param map the map from which to construct the new Ray by inverse mapping. | ||
145 | /// @warning Assumes a linear map and a normalized direction. | ||
146 | /// @details The requirement that the direction is normalized | ||
147 | /// follows from the transformation of t0 and t1 - and that fact that | ||
148 | /// we want applyMap and applyInverseMap to be inverse operations. | ||
149 | template<typename MapType> | ||
150 | 1048586 | inline Ray applyInverseMap(const MapType& map) const | |
151 | { | ||
152 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1048586 times.
|
1048586 | assert(map.isLinear()); |
153 | ✗ | assert(math::isRelOrApproxEqual(mDir.length(), RealT(1), Tolerance<RealT>::value(), Delta<RealT>::value())); | |
154 | 1048586 | const Vec3T eye = map.applyInverseMap(mEye); | |
155 | 1048586 | const Vec3T dir = map.applyInverseJacobian(mDir); | |
156 | const RealT length = dir.length(); | ||
157 | 1048586 | return Ray(eye, dir/length, length*mTimeSpan.t0, length*mTimeSpan.t1); | |
158 | } | ||
159 | |||
160 | /// @brief Return a new ray in world space, assuming the existing | ||
161 | /// ray is represented in the index space of the specified grid. | ||
162 | template<typename GridType> | ||
163 | inline Ray indexToWorld(const GridType& grid) const | ||
164 | { | ||
165 | return this->applyMap(*(grid.transform().baseMap())); | ||
166 | } | ||
167 | |||
168 | /// @brief Return a new ray in the index space of the specified | ||
169 | /// grid, assuming the existing ray is represented in world space. | ||
170 | template<typename GridType> | ||
171 | 1048584 | inline Ray worldToIndex(const GridType& grid) const | |
172 | { | ||
173 |
1/2✓ Branch 1 taken 1048584 times.
✗ Branch 2 not taken.
|
2097168 | return this->applyInverseMap(*(grid.transform().baseMap())); |
174 | } | ||
175 | |||
176 | /// @brief Return true if this ray intersects the specified sphere. | ||
177 | /// @param center The center of the sphere in the same space as this ray. | ||
178 | /// @param radius The radius of the sphere in the same units as this ray. | ||
179 | /// @param t0 The first intersection point if an intersection exists. | ||
180 | /// @param t1 The second intersection point if an intersection exists. | ||
181 | /// @note If the return value is true, i.e. a hit, and t0 = | ||
182 | /// this->t0() or t1 == this->t1() only one true intersection exist. | ||
183 |
2/2✓ Branch 0 taken 205870 times.
✓ Branch 1 taken 1 times.
|
205871 | inline bool intersects(const Vec3T& center, RealT radius, RealT& t0, RealT& t1) const |
184 | { | ||
185 | const Vec3T origin = mEye - center; | ||
186 | const RealT A = mDir.lengthSqr(); | ||
187 | 205871 | const RealT B = 2 * mDir.dot(origin); | |
188 | 205871 | const RealT C = origin.lengthSqr() - radius * radius; | |
189 | 205871 | const RealT D = B * B - 4 * A * C; | |
190 | |||
191 |
2/2✓ Branch 0 taken 205870 times.
✓ Branch 1 taken 1 times.
|
205871 | if (D < 0) return false; |
192 | |||
193 |
1/2✓ Branch 0 taken 205870 times.
✗ Branch 1 not taken.
|
205870 | const RealT Q = RealT(-0.5)*(B<0 ? (B + Sqrt(D)) : (B - Sqrt(D))); |
194 | |||
195 | 205870 | t0 = Q / A; | |
196 | 205870 | t1 = C / Q; | |
197 | |||
198 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 205870 times.
|
205870 | if (t0 > t1) std::swap(t0, t1); |
199 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 205869 times.
|
205870 | if (t0 < mTimeSpan.t0) t0 = mTimeSpan.t0; |
200 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 205870 times.
|
205870 | if (t1 > mTimeSpan.t1) t1 = mTimeSpan.t1; |
201 | 205870 | return t0 <= t1; | |
202 | } | ||
203 | |||
204 | /// @brief Return true if this ray intersects the specified sphere. | ||
205 | /// @param center The center of the sphere in the same space as this ray. | ||
206 | /// @param radius The radius of the sphere in the same units as this ray. | ||
207 | inline bool intersects(const Vec3T& center, RealT radius) const | ||
208 | { | ||
209 | RealT t0, t1; | ||
210 | return this->intersects(center, radius, t0, t1)>0; | ||
211 | } | ||
212 | |||
213 | /// @brief Return true if this ray intersects the specified sphere. | ||
214 | /// @note For intersection this ray is clipped to the two intersection points. | ||
215 | /// @param center The center of the sphere in the same space as this ray. | ||
216 | /// @param radius The radius of the sphere in the same units as this ray. | ||
217 | inline bool clip(const Vec3T& center, RealT radius) | ||
218 | { | ||
219 | RealT t0, t1; | ||
220 | const bool hit = this->intersects(center, radius, t0, t1); | ||
221 | if (hit) mTimeSpan.set(t0, t1); | ||
222 | return hit; | ||
223 | } | ||
224 | |||
225 | /// @brief Return true if the Ray intersects the specified | ||
226 | /// axisaligned bounding box. | ||
227 | /// @param bbox Axis-aligned bounding box in the same space as the Ray. | ||
228 | /// @param t0 If an intersection is detected this is assigned | ||
229 | /// the time for the first intersection point. | ||
230 | /// @param t1 If an intersection is detected this is assigned | ||
231 | /// the time for the second intersection point. | ||
232 | template<typename BBoxT> | ||
233 | 1048605 | inline bool intersects(const BBoxT& bbox, RealT& t0, RealT& t1) const | |
234 | { | ||
235 | mTimeSpan.get(t0, t1); | ||
236 |
2/2✓ Branch 0 taken 2430033 times.
✓ Branch 1 taken 266281 times.
|
2696322 | for (int i = 0; i < 3; ++i) { |
237 |
4/6✗ Branch 0 not taken.
✓ Branch 1 taken 2430027 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2430027 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 2430011 times.
|
2430039 | RealT a = (bbox.min()[i] - mEye[i]) * mInvDir[i]; |
238 | 2430039 | RealT b = (bbox.max()[i] - mEye[i]) * mInvDir[i]; | |
239 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2430015 times.
|
2430039 | if (a > b) std::swap(a, b); |
240 |
2/2✓ Branch 0 taken 657438 times.
✓ Branch 1 taken 1772595 times.
|
2430039 | if (a > t0) t0 = a; |
241 |
2/2✓ Branch 0 taken 1048605 times.
✓ Branch 1 taken 1381428 times.
|
2430039 | if (b < t1) t1 = b; |
242 |
2/2✓ Branch 0 taken 1647711 times.
✓ Branch 1 taken 782322 times.
|
2430039 | if (t0 > t1) return false; |
243 | } | ||
244 | return true; | ||
245 | } | ||
246 | |||
247 | /// @brief Return true if this ray intersects the specified bounding box. | ||
248 | /// @param bbox Axis-aligned bounding box in the same space as this ray. | ||
249 | template<typename BBoxT> | ||
250 | inline bool intersects(const BBoxT& bbox) const | ||
251 | { | ||
252 | RealT t0, t1; | ||
253 | 1 | return this->intersects(bbox, t0, t1); | |
254 | } | ||
255 | |||
256 | /// @brief Return true if this ray intersects the specified bounding box. | ||
257 | /// @note For intersection this ray is clipped to the two intersection points. | ||
258 | /// @param bbox Axis-aligned bounding box in the same space as this ray. | ||
259 | template<typename BBoxT> | ||
260 | ✗ | inline bool clip(const BBoxT& bbox) | |
261 | { | ||
262 | RealT t0, t1; | ||
263 | 1048600 | const bool hit = this->intersects(bbox, t0, t1); | |
264 |
4/8✓ Branch 0 taken 266270 times.
✓ Branch 1 taken 782320 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
1048600 | if (hit) mTimeSpan.set(t0, t1); |
265 | ✗ | return hit; | |
266 | } | ||
267 | |||
268 | /// @brief Return true if the Ray intersects the plane specified | ||
269 | /// by a normal and distance from the origin. | ||
270 | /// @param normal Normal of the plane. | ||
271 | /// @param distance Distance of the plane to the origin. | ||
272 | /// @param t Time of intersection, if one exists. | ||
273 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
|
10 | inline bool intersects(const Vec3T& normal, RealT distance, RealT& t) const |
274 | { | ||
275 | const RealT cosAngle = mDir.dot(normal); | ||
276 | if (math::isApproxZero(cosAngle)) return false;//parallel | ||
277 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
|
9 | t = (distance - mEye.dot(normal))/cosAngle; |
278 | return this->test(t); | ||
279 | } | ||
280 | |||
281 | /// @brief Return true if the Ray intersects the plane specified | ||
282 | /// by a normal and point. | ||
283 | /// @param normal Normal of the plane. | ||
284 | /// @param point Point in the plane. | ||
285 | /// @param t Time of intersection, if one exists. | ||
286 | inline bool intersects(const Vec3T& normal, const Vec3T& point, RealT& t) const | ||
287 | { | ||
288 | return this->intersects(normal, point.dot(normal), t); | ||
289 | } | ||
290 | |||
291 | private: | ||
292 | Vec3T mEye, mDir, mInvDir; | ||
293 | TimeSpan mTimeSpan; | ||
294 | }; // end of Ray class | ||
295 | |||
296 | |||
297 | /// @brief Output streaming of the Ray class. | ||
298 | /// @note Primarily intended for debugging. | ||
299 | template<typename RealT> | ||
300 | inline std::ostream& operator<<(std::ostream& os, const Ray<RealT>& r) | ||
301 | { | ||
302 | os << "eye=" << r.eye() << " dir=" << r.dir() << " 1/dir="<<r.invDir() | ||
303 | << " t0=" << r.t0() << " t1=" << r.t1(); | ||
304 | return os; | ||
305 | } | ||
306 | |||
307 | } // namespace math | ||
308 | } // namespace OPENVDB_VERSION_NAME | ||
309 | } // namespace openvdb | ||
310 | |||
311 | #endif // OPENVDB_MATH_RAY_HAS_BEEN_INCLUDED | ||
312 |