10#ifndef NANOVDB_HDDA_H_HAS_BEEN_INCLUDED
11#define NANOVDB_HDDA_H_HAS_BEEN_INCLUDED
14#define ENFORCE_FORWARD_STEPPING
28template<
typename RayT,
typename CoordT = Coord>
51 const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
53 for (
int axis = 0; axis < 3; ++axis) {
54 if (dir[axis] ==
RealT(0)) {
57 }
else if (inv[axis] > 0) {
59 mNext[axis] = mT0 + (mVoxel[axis] +
dim - pos[axis]) * inv[axis];
60 mDelta[axis] = inv[axis];
63 mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
64 mDelta[axis] = -inv[axis];
80 Coord voxelMin = mVoxel & (~(
dim - 1));
83 const Vec3T &pos = ray(mT0), &inv = ray.invDir();
94 for (
int axis = 0; axis < 3; ++axis) {
97 mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
99 mNext[axis] +=
dim * inv[axis];
123 mNext[axis] += mDim * mDelta[axis];
124 mVoxel[axis] += mDim * mStep[axis];
152 return fminf(mT1, fminf(mNext[0], fminf(mNext[1], mNext[2])));
154 return std::min(mT1, std::min(mNext[0], std::min(mNext[1], mNext[2])));
163#ifdef ENFORCE_FORWARD_STEPPING
166 if (mNext[axis] <= mT0) {
167 mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6f;
171 mNext[ axis] += mDim * mDelta[axis];
172 mVoxel[axis] += mDim * mStep[ axis];
178 CoordT mVoxel, mStep;
189template<
typename RayT,
typename AccT>
193 if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20)
195 static const float Delta = 1.0001f;
198 const auto v0 = acc.getValue(ijk);
199 while (hdda.
step()) {
201 hdda.
update(ray, acc.getDim(ijk, ray));
202 if (hdda.
dim() > 1 || !acc.isActive(ijk))
204 while (hdda.
step() && acc.isActive(hdda.
voxel())) {
205 v = acc.getValue(hdda.
voxel());
216template<
typename RayT,
typename AccT>
217[[deprecated(
"Use zeroCrossing(ray, acc, ijk, v, t)")]]
225template<
typename RayT,
typename AccT>
226inline __hostdev__ bool isoCrossing(RayT& ray, AccT& acc,
Coord& ijk,
typename AccT::ValueType& v,
float& t,
const typename AccT::ValueType& iso = 0.0f)
229 if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20)
return false;
230 static const float Delta = 1.0001f;
233 const auto v0 = acc.getValue(ijk) - iso;
234 while (hdda.
step()) {
236 hdda.
update(ray, acc.getDim(ijk, ray));
237 if (hdda.
dim() > 1 || !acc.isActive(ijk))
continue;
238 while (hdda.
step() && acc.isActive(hdda.
voxel())) {
239 v = acc.getValue(hdda.
voxel()) - iso;
258template<
typename RayT,
typename CoordT = Coord,
int Dim = 1>
261 static_assert(Dim >= 1,
"Dim must be >= 1");
282 const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
284 for (
int axis = 0; axis < 3; ++axis) {
285 if (dir[axis] ==
RealT(0)) {
288 }
else if (inv[axis] > 0) {
290 mNext[axis] = (mT0 + (mVoxel[axis] + Dim - pos[axis]) * inv[axis]);
291 mDelta[axis] = inv[axis];
294 mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
295 mDelta[axis] = -inv[axis];
318#ifdef ENFORCE_FORWARD_STEPPING
319 if (mNext[axis] <= mT0) {
320 mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6f;
324 mNext[axis] += mDelta[axis];
325 mVoxel[axis] += mStep[axis];
352 return Min(mT1,
Min(mNext[0],
Min(mNext[1], mNext[2])));
365#ifdef ENFORCE_FORWARD_STEPPING
366 if (mNext[axis] <= mT0) {
367 mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6f;
371 mNext[axis] += mDelta[axis];
372 mVoxel[axis] += mStep[axis];
377 CoordT mVoxel, mStep;
383template<
typename RayT,
typename NodeT>
388 if (!ray.clip(node.bbox())) {
392 const float t0 = ray.t0();
394 static const float Delta = 1.0001f;
404 if (bbox.isInside(ijk) ==
false)
407 v = node.getValue(ijk);
416template<
typename RayT,
typename NodeT>
417[[deprecated(
"Use zeroCrossingNode(ray, node, v0, ijk, v, t)")]]
429template<
typename RayT,
typename AccT>
432 if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20) {
435 static const float Delta = 1.0001f;
438 for (
HDDA<RayT, Coord> hdda(ray, acc.getDim(ijk, ray)); !acc.isActive(ijk); hdda.
update(ray, acc.getDim(ijk, ray))) {
439 if (!hdda.step())
return false;
440 t = hdda.time() +
Delta;
450template<
typename NodeT,
typename RayT,
typename AccT,
typename CoordT = Coord>
454 using ChildT =
typename NodeT::ChildNodeType;
468 if (!mRay.clip(mAcc.root().bbox()))
473 static const float Eps = 0.000001f;
474 const float t0 = mRay.t0() + Eps;
475 const float t1 = mRay.t1() - Eps;
480 const uint32_t dim = mAcc.getDim(ijk, mRay);
483 mT0 = (dim <= ChildT::dim()) ? mHdda.time() : -1;
495 static const float Delta = 0.01f;
501 auto currentNode = mAcc.template getNode<NodeT>();
504 hddaIsValid = mHdda.step();
506 const auto nextDim = mAcc.getDim(nextIjk, mRay);
507 mHdda.update(mRay, (
int)
Max(nextDim, NodeT::dim()));
508 mT0 = (nextDim <= ChildT::dim()) ? mHdda.time() : -1;
511 t1 =
Min(mTmax, mHdda.time());
514 if (t0 >= t1 || currentNode ==
nullptr)
521 }
while (hddaIsValid);
545template<
typename AccT,
typename RayT,
typename CoordT = Coord>
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition Math.h:346
static __hostdev__ Coord Floor(const Vec3T &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition Math.h:563
A Digital Differential Analyzer. Unlike HDDA (defined above) this DDA uses a fixed step-size defined ...
Definition HDDA.h:260
__hostdev__ const CoordT & voxel() const
Return the index coordinates of the next node or voxel intersected by the ray. If Log2Dim = 0 the ret...
Definition HDDA.h:335
CoordT CoordType
Definition HDDA.h:268
__hostdev__ RealType maxTime() const
Return the maximum time (parameterized along the Ray).
Definition HDDA.h:345
__hostdev__ RealType time() const
Return the time (parameterized along the Ray) of the first hit of a tree node of size 2^Log2Dim.
Definition HDDA.h:342
__hostdev__ int nextAxis() const
Definition HDDA.h:355
__hostdev__ 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 HDDA.h:350
__hostdev__ DDA(const RayT &ray)
ctor from ray and dimension at which the DDA marches
Definition HDDA.h:274
__hostdev__ bool step()
Increment the voxel index to next intersected voxel or node and returns true if the step in time does...
Definition HDDA.h:305
DDA()=default
Default ctor.
RealType RealT
Definition HDDA.h:265
Vec3Type Vec3T
Definition HDDA.h:267
__hostdev__ void init(const RayT &ray)
Simular to init above except it uses the bounds of the input ray.
Definition HDDA.h:301
__hostdev__ void init(const RayT &ray, RealT startTime, RealT maxTime)
Re-initializes the DDA.
Definition HDDA.h:277
typename RayT::Vec3Type Vec3Type
Definition HDDA.h:266
typename RayT::RealType RealType
Definition HDDA.h:264
A Digital Differential Analyzer specialized for OpenVDB grids.
Definition HDDA.h:30
__hostdev__ const CoordT & voxel() const
Return the index coordinates of the next node or voxel intersected by the ray. If Log2Dim = 0 the ret...
Definition HDDA.h:134
CoordT CoordType
Definition HDDA.h:36
__hostdev__ RealType maxTime() const
Return the maximum time (parameterized along the Ray).
Definition HDDA.h:144
__hostdev__ void init(const RayT &ray, int dim)
Simular to init above except it uses the bounds of the input ray.
Definition HDDA.h:70
__hostdev__ HDDA(const RayT &ray, int dim)
ctor from ray and dimension at which the DDA marches
Definition HDDA.h:42
__hostdev__ RealType time() const
Return the time (parameterized along the Ray) of the first hit of a tree node of size 2^Log2Dim.
Definition HDDA.h:141
__hostdev__ 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 HDDA.h:149
__hostdev__ void init(const RayT &ray, RealT startTime, RealT maxTime, int dim)
Re-initializes the HDDA.
Definition HDDA.h:45
__hostdev__ int dim() const
Definition HDDA.h:105
__hostdev__ bool step()
Increment the voxel index to next intersected voxel or node and returns true if the step in time does...
Definition HDDA.h:109
RealType RealT
Definition HDDA.h:33
Vec3Type Vec3T
Definition HDDA.h:35
typename RayT::Vec3Type Vec3Type
Definition HDDA.h:34
HDDA()=default
Default ctor.
typename RayT::RealType RealType
Definition HDDA.h:32
__hostdev__ bool update(const RayT &ray, int dim)
Updates the HDDA to march with the specified dimension.
Definition HDDA.h:73
__hostdev__ PointTreeMarcher(AccT &acc)
Definition HDDA.h:550
__hostdev__ bool init(RayT ray)
Initiates this instance with a ray in index space.
Definition HDDA.h:561
CoordT CoordType
Definition HDDA.h:457
__hostdev__ bool step(const NodeT **node, float &t0, float &t1)
step the ray through the tree. If the ray hits a node then populate t0 & t1, and the node.
Definition HDDA.h:491
__hostdev__ const RayT & ray() const
Definition HDDA.h:526
typename NodeT::ChildNodeType ChildT
Definition HDDA.h:454
__hostdev__ RayT & ray()
Definition HDDA.h:528
RealType RealT
Definition HDDA.h:456
__hostdev__ bool init(const RayT &indexRay)
Initialize the TreeMarcher with an index-space ray.
Definition HDDA.h:465
__hostdev__ TreeMarcher(AccT &acc)
Definition HDDA.h:459
typename RayT::RealType RealType
Definition HDDA.h:455
#define __hostdev__
Definition SampleFromVoxels.h:29
Definition DitherLUT.h:19
__hostdev__ int MinIndex(const Vec3T &v)
Definition Math.h:295
__hostdev__ bool ZeroCrossing(RayT &ray, AccT &acc, Coord &ijk, typename AccT::ValueType &v, float &t)
Definition HDDA.h:218
__hostdev__ bool isoCrossing(RayT &ray, AccT &acc, Coord &ijk, typename AccT::ValueType &v, float &t, const typename AccT::ValueType &iso=0.0f)
Definition HDDA.h:226
__hostdev__ bool zeroCrossingNode(RayT &ray, const NodeT &node, float v0, nanovdb::math::Coord &ijk, float &v, float &t)
Definition HDDA.h:384
__hostdev__ bool ZeroCrossingNode(RayT &ray, const NodeT &node, float v0, nanovdb::math::Coord &ijk, float &v, float &t)
Definition HDDA.h:418
__hostdev__ CoordT RoundDown(const Vec3T< RealT > &xyz)
Definition Math.h:270
__hostdev__ Type Max(Type a, Type b)
Definition Math.h:154
__hostdev__ bool firstActive(RayT &ray, AccT &acc, Coord &ijk, float &t)
returns true if the ray intersects an active value at any level of the grid in the accessor....
Definition HDDA.h:430
__hostdev__ bool zeroCrossing(RayT &ray, AccT &acc, Coord &ijk, typename AccT::ValueType &v, float &t)
returns true if the ray intersects a zero-crossing at the voxel level of the grid in the accessor The...
Definition HDDA.h:190
__hostdev__ Type Min(Type a, Type b)
Definition Math.h:133
Delta for small floating-point offsets.
Definition Math.h:73
static T value()
Definition Math.h:121
static constexpr bool value
Definition Util.h:344