10 #ifndef OPENVDB_MATH_DDA_HAS_BEEN_INCLUDED 11 #define OPENVDB_MATH_DDA_HAS_BEEN_INCLUDED 34 template<
typename RayT, Index Log2Dim = 0>
40 using Vec3Type =
typename RayT::Vec3Type;
46 DDA(
const RayT& ray) { this->init(ray); }
48 DDA(
const RayT& ray,
RealT startTime) { this->init(ray, startTime); }
50 DDA(
const RayT& ray,
RealT startTime,
RealT maxTime) { this->init(ray, startTime, maxTime); }
55 static const int DIM = 1 << Log2Dim;
58 const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
59 mVoxel = Coord::floor(pos) & (~(DIM-1));
60 for (
int axis = 0; axis < 3; ++axis) {
65 }
else if (inv[axis] > 0) {
67 mNext[axis] = mT0 + (mVoxel[axis] + DIM - pos[axis]) * inv[axis];
68 mDelta[axis] = mStep[axis] * inv[axis];
71 mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
72 mDelta[axis] = mStep[axis] * inv[axis];
77 inline void init(
const RayT& ray) { this->
init(ray, ray.t0(), ray.t1()); }
79 inline void init(
const RayT& ray,
RealT startTime) { this->
init(ray, startTime, ray.t1()); }
86 mT0 = mNext[stepAxis];
87 mNext[stepAxis] += mDelta[stepAxis];
88 mVoxel[stepAxis] += mStep[stepAxis];
116 void print(std::ostream& os = std::cout)
const 118 os <<
"Dim=" << (1<<Log2Dim) <<
" time=" << mT0 <<
" next()=" 119 << this->next() <<
" voxel=" << mVoxel <<
" next=" << mNext
120 <<
" delta=" << mDelta <<
" step=" << mStep << std::endl;
131 template<
typename RayT, Index Log2Dim>
132 inline std::ostream& operator<<(std::ostream& os, const DDA<RayT, Log2Dim>& dda)
134 os <<
"Dim=" << (1<<Log2Dim) <<
" time=" << dda.time()
135 <<
" next()=" << dda.next() <<
" voxel=" << dda.voxel();
144 template<
typename TreeT,
int NodeLevel>
147 using ChainT =
typename TreeT::RootNodeType::NodeChainType;
148 using NodeT =
typename ChainT::template Get<NodeLevel>;
150 template <
typename TesterT>
151 static bool test(TesterT& tester)
155 if (tester.template hasNode<NodeT>(dda.voxel())) {
156 tester.setRange(dda.time(), dda.next());
166 template<
typename TreeT>
169 template <
typename TesterT>
170 static bool test(TesterT& tester)
173 tester.
init(dda.time());
174 do {
if (tester(dda.voxel(), dda.next()))
return true; }
while(dda.step());
187 template <
typename TreeT,
typename RayT,
int ChildNodeLevel>
192 using ChainT =
typename TreeT::RootNodeType::NodeChainType;
193 using NodeT =
typename ChainT::template Get<ChildNodeLevel>;
198 template <
typename AccessorT>
202 if (ray.valid()) this->march(ray, acc, t);
210 template <
typename AccessorT,
typename ListT>
211 void hits(RayT& ray, AccessorT &acc, ListT& times)
215 this->hits(ray, acc, times, t);
216 if (t.valid()) times.push_back(t);
223 template <
typename AccessorT>
224 bool march(RayT& ray, AccessorT &acc,
TimeSpanT& t)
228 if (acc.template probeConstNode<NodeT>(mDDA.voxel()) !=
nullptr) {
229 ray.setTimes(mDDA.time(), mDDA.next());
230 if (mHDDA.march(ray, acc, t))
return true;
231 }
else if (acc.isValueOn(mDDA.voxel())) {
232 if (t.t0<0) t.t0 = mDDA.time();
233 }
else if (t.t0>=0) {
235 if (t.valid())
return true;
238 }
while (mDDA.step());
239 if (t.t0>=0) t.t1 = mDDA.maxTime();
247 template <
typename AccessorT,
typename ListT>
248 void hits(RayT& ray, AccessorT &acc, ListT& times,
TimeSpanT& t)
252 if (acc.template probeConstNode<NodeT>(mDDA.voxel()) !=
nullptr) {
253 ray.setTimes(mDDA.time(), mDDA.next());
254 mHDDA.
hits(ray, acc, times, t);
255 }
else if (acc.isValueOn(mDDA.voxel())) {
256 if (t.t0<0) t.t0 = mDDA.time();
257 }
else if (t.t0>=0) {
259 if (t.valid()) times.push_back(t);
262 }
while (mDDA.step());
263 if (t.t0>=0) t.t1 = mDDA.maxTime();
267 VolumeHDDA<TreeT, RayT, ChildNodeLevel-1> mHDDA;
272 template <
typename TreeT,
typename RayT>
277 using LeafT =
typename TreeT::LeafNodeType;
282 template <
typename AccessorT>
286 if (ray.valid()) this->march(ray, acc, t);
290 template <
typename AccessorT,
typename ListT>
291 void hits(RayT& ray, AccessorT &acc, ListT& times)
295 this->hits(ray, acc, times, t);
296 if (t.valid()) times.push_back(t);
303 template <
typename AccessorT>
304 bool march(RayT& ray, AccessorT &acc,
TimeSpanT& t)
308 if (acc.template probeConstNode<LeafT>(mDDA.voxel()) ||
309 acc.isValueOn(mDDA.voxel())) {
310 if (t.t0<0) t.t0 = mDDA.time();
311 }
else if (t.t0>=0) {
313 if (t.valid())
return true;
316 }
while (mDDA.step());
317 if (t.t0>=0) t.t1 = mDDA.maxTime();
321 template <
typename AccessorT,
typename ListT>
322 void hits(RayT& ray, AccessorT &acc, ListT& times,
TimeSpanT& t)
326 if (acc.template probeConstNode<LeafT>(mDDA.voxel()) ||
327 acc.isValueOn(mDDA.voxel())) {
328 if (t.t0<0) t.t0 = mDDA.time();
329 }
else if (t.t0>=0) {
331 if (t.valid()) times.push_back(t);
334 }
while (mDDA.step());
335 if (t.t0>=0) t.t1 = mDDA.maxTime();
344 #endif // OPENVDB_MATH_DDA_HAS_BEEN_INCLUDED RealType next() const
Return the time (parameterized along the Ray) of the second (i.e. next) hit of a tree node of size 2^...
Definition: DDA.h:112
typename openvdb::v12_0::tree::Tree::RootNodeType::NodeChainType ChainT
Definition: DDA.h:192
typename TreeT::LeafNodeType LeafT
Definition: DDA.h:277
RealType time() const
Return the time (parameterized along the Ray) of the first hit of a tree node of size 2^Log2Dim...
Definition: DDA.h:104
typename ChainT::template Get< ChildNodeLevel > NodeT
Definition: DDA.h:193
Vec3Type Vec3T
Definition: DDA.h:41
typename RayT::RealType RealType
Definition: DDA.h:38
typename RayType::TimeSpan TimeSpanT
Definition: DDA.h:194
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
DDA(const RayT &ray, RealT startTime, RealT maxTime)
Definition: DDA.h:50
DDA(const RayT &ray, RealT startTime)
Definition: DDA.h:48
bool step()
Increment the voxel index to next intersected voxel or node and returns true if the step in time does...
Definition: DDA.h:83
DDA()
uninitialized constructor
Definition: DDA.h:44
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:25
const Coord & voxel() const
Return the index coordinates of the next node or voxel intersected by the ray. If Log2Dim = 0 the ret...
Definition: DDA.h:97
Helper class that implements Hierarchical Digital Differential Analyzers and is specialized for ray i...
Definition: DDA.h:145
TimeSpanT march(RayT &ray, AccessorT &acc)
Definition: DDA.h:283
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:656
RealType RealT
Definition: DDA.h:39
void print(std::ostream &os=std::cout) const
Print information about this DDA for debugging.
Definition: DDA.h:116
static bool test(TesterT &tester)
Definition: DDA.h:151
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:337
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
VolumeHDDA()
Definition: DDA.h:196
A Digital Differential Analyzer specialized for OpenVDB grids.
Definition: DDA.h:35
Definition: Exceptions.h:13
typename TreeT::RootNodeType::NodeChainType ChainT
Definition: DDA.h:147
TimeSpanT march(RayT &ray, AccessorT &acc)
Definition: DDA.h:199
Helper class that implements Hierarchical Digital Differential Analyzers for ray intersections agains...
Definition: DDA.h:188
void init(const RayT &ray)
Definition: DDA.h:77
VolumeHDDA()
Definition: DDA.h:280
RealType maxTime() const
Return the maximum time (parameterized along the Ray).
Definition: DDA.h:107
static bool test(TesterT &tester)
Definition: DDA.h:170
DDA(const RayT &ray)
Definition: DDA.h:46
void hits(RayT &ray, AccessorT &acc, ListT ×)
Definition: DDA.h:211
void hits(RayT &ray, AccessorT &acc, ListT ×)
Definition: DDA.h:291
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
typename ChainT::template Get< NodeLevel > NodeT
Definition: DDA.h:148
void init(const RayT &ray, RealT startTime)
Definition: DDA.h:79
typename RayT::TimeSpan TimeSpanT
Definition: DDA.h:278
void init(const RayT &ray, RealT startTime, RealT maxTime)
Definition: DDA.h:52
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:930