37 #ifndef OPENVDB_MATH_DDA_HAS_BEEN_INCLUDED
38 #define OPENVDB_MATH_DDA_HAS_BEEN_INCLUDED
43 #include <openvdb/Types.h>
46 #include <boost/mpl/at.hpp>
61 template<
typename RayT, Index Log2Dim = 0>
73 DDA(
const RayT& ray) { this->init(ray); }
75 DDA(
const RayT& ray,
RealT startTime) { this->init(ray, startTime); }
77 DDA(
const RayT& ray,
RealT startTime,
RealT maxTime) { this->init(ray, startTime, maxTime); }
81 assert(startTime <= maxTime);
82 static const int DIM = 1 << Log2Dim;
85 const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
87 for (
int axis = 0; axis < 3; ++axis) {
92 }
else if (inv[axis] > 0) {
94 mNext[axis] = mT0 + (mVoxel[axis] + DIM - pos[axis]) * inv[axis];
95 mDelta[axis] = mStep[axis] * inv[axis];
98 mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
99 mDelta[axis] = mStep[axis] * inv[axis];
104 inline void init(
const RayT& ray) { this->
init(ray, ray.t0(), ray.t1()); }
106 inline void init(
const RayT& ray,
RealT startTime) { this->
init(ray, startTime, ray.t1()); }
113 mT0 = mNext[stepAxis];
114 mNext[stepAxis] += mDelta[stepAxis];
115 mVoxel[stepAxis] += mStep[stepAxis];
131 inline RealType
time()
const {
return mT0; }
134 inline RealType
maxTime()
const {
return mT1; }
139 inline RealType
next()
const {
return math::Min(mT1, mNext[0], mNext[1], mNext[2]); }
143 void print(std::ostream& os = std::cout)
const
145 os <<
"Dim=" << (1<<Log2Dim) <<
" time=" << mT0 <<
" next()="
146 << this->next() <<
" voxel=" << mVoxel <<
" next=" << mNext
147 <<
" delta=" << mDelta <<
" step=" << mStep << std::endl;
158 template<
typename RayT, Index Log2Dim>
161 os <<
"Dim=" << (1<<Log2Dim) <<
" time=" << dda.
time()
162 <<
" next()=" << dda.
next() <<
" voxel=" << dda.
voxel();
171 template<
typename TreeT,
int NodeLevel>
174 typedef typename TreeT::RootNodeType::NodeChainType
ChainT;
175 typedef typename boost::mpl::at<ChainT, boost::mpl::int_<NodeLevel> >::type
NodeT;
177 template <
typename TesterT>
178 static bool test(TesterT& tester)
182 if (tester.template hasNode<NodeT>(dda.voxel())) {
183 tester.setRange(dda.time(), dda.next());
193 template<
typename TreeT>
196 template <
typename TesterT>
197 static bool test(TesterT& tester)
200 tester.
init(dda.time());
201 do {
if (tester(dda.voxel(), dda.next()))
return true; }
while(dda.step());
214 template <
typename TreeT,
typename RayT,
int ChildNodeLevel>
219 typedef typename TreeT::RootNodeType::NodeChainType
ChainT;
220 typedef typename boost::mpl::at<ChainT, boost::mpl::int_<ChildNodeLevel> >::type
NodeT;
225 template <
typename AccessorT>
229 if (ray.valid()) this->march(ray, acc, t);
237 template <
typename AccessorT,
typename ListT>
238 void hits(RayT& ray, AccessorT &acc, ListT& times)
242 this->hits(ray, acc, times, t);
243 if (t.valid()) times.push_back(t);
250 template <
typename AccessorT>
251 bool march(RayT& ray, AccessorT &acc,
TimeSpanT& t)
255 if (acc.template probeConstNode<NodeT>(mDDA.voxel()) != NULL) {
256 ray.setTimes(mDDA.time(), mDDA.next());
257 if (mHDDA.march(ray, acc, t))
return true;
258 }
else if (acc.isValueOn(mDDA.voxel())) {
259 if (t.t0<0) t.t0 = mDDA.time();
260 }
else if (t.t0>=0) {
262 if (t.valid())
return true;
265 }
while (mDDA.step());
266 if (t.t0>=0) t.t1 = mDDA.maxTime();
274 template <
typename AccessorT,
typename ListT>
275 void hits(RayT& ray, AccessorT &acc, ListT& times, TimeSpanT& t)
279 if (acc.template probeConstNode<NodeT>(mDDA.voxel()) != NULL) {
280 ray.setTimes(mDDA.time(), mDDA.next());
281 mHDDA.
hits(ray, acc, times, t);
282 }
else if (acc.isValueOn(mDDA.voxel())) {
283 if (t.t0<0) t.t0 = mDDA.time();
284 }
else if (t.t0>=0) {
286 if (t.valid()) times.push_back(t);
289 }
while (mDDA.step());
290 if (t.t0>=0) t.t1 = mDDA.maxTime();
293 math::DDA<RayT, NodeT::TOTAL> mDDA;
294 VolumeHDDA<TreeT, RayT, ChildNodeLevel-1> mHDDA;
299 template <
typename TreeT,
typename RayT>
304 typedef typename TreeT::LeafNodeType
LeafT;
309 template <
typename AccessorT>
313 if (ray.valid()) this->march(ray, acc, t);
317 template <
typename AccessorT,
typename ListT>
318 void hits(RayT& ray, AccessorT &acc, ListT& times)
322 this->hits(ray, acc, times, t);
323 if (t.valid()) times.push_back(t);
330 template <
typename AccessorT>
331 bool march(RayT& ray, AccessorT &acc,
TimeSpanT& t)
335 if (acc.template probeConstNode<LeafT>(mDDA.voxel()) ||
336 acc.isValueOn(mDDA.voxel())) {
337 if (t.t0<0) t.t0 = mDDA.time();
338 }
else if (t.t0>=0) {
340 if (t.valid())
return true;
343 }
while (mDDA.step());
344 if (t.t0>=0) t.t1 = mDDA.maxTime();
348 template <
typename AccessorT,
typename ListT>
349 void hits(RayT& ray, AccessorT &acc, ListT& times, TimeSpanT& t)
353 if (acc.template probeConstNode<LeafT>(mDDA.voxel()) ||
354 acc.isValueOn(mDDA.voxel())) {
355 if (t.t0<0) t.t0 = mDDA.time();
356 }
else if (t.t0>=0) {
358 if (t.valid()) times.push_back(t);
361 }
while (mDDA.step());
362 if (t.t0>=0) t.t1 = mDDA.maxTime();
364 math::DDA<RayT, LeafT::TOTAL> mDDA;
371 #endif // OPENVDB_MATH_DDA_HAS_BEEN_INCLUDED