10#ifndef NANOVDB_HDDA_H_HAS_BEEN_INCLUDED
11#define NANOVDB_HDDA_H_HAS_BEEN_INCLUDED
14#define ENFORCE_FORWARD_STEPPING
32template<
typename RayT,
typename CoordT = Coord>
55 const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
57 for (
int axis = 0; axis < 3; ++axis) {
58 if (dir[axis] ==
RealT(0)) {
61 }
else if (inv[axis] > 0) {
63 mNext[axis] = mT0 + (
RealT(mVoxel[axis] +
dim) - pos[axis]) * inv[axis];
64 mDelta[axis] = inv[axis];
67 mNext[axis] = mT0 + (
RealT(mVoxel[axis]) - pos[axis]) * inv[axis];
68 mDelta[axis] = -inv[axis];
84 Coord voxelMin = mVoxel & (~(
dim - 1));
87 const Vec3T &pos = ray(mT0), &inv = ray.invDir();
98 for (
int axis = 0; axis < 3; ++axis) {
101 mNext[axis] = mT0 + (
RealT(mVoxel[axis]) - pos[axis]) * inv[axis];
103 mNext[axis] +=
RealT(
dim) * inv[axis];
127 mNext[axis] +=
RealT(mDim) * mDelta[axis];
128 mVoxel[axis] += mDim * mStep[axis];
156 return fminf(mT1, fminf(mNext[0], fminf(mNext[1], mNext[2])));
158 return std::min(mT1, std::min(mNext[0], std::min(mNext[1], mNext[2])));
167#ifdef ENFORCE_FORWARD_STEPPING
170 if (mNext[axis] <= mT0) {
171 mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6f;
175 mNext[ axis] +=
RealT(mDim) * mDelta[axis];
176 mVoxel[axis] += mDim * mStep[ axis];
182 CoordT mVoxel, mStep;
193template<
typename RayT,
typename AccT>
197 if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20)
199 static const float Delta = 1.0001f;
202 const auto v0 = acc.getValue(ijk);
203 while (hdda.
step()) {
205 hdda.
update(ray, acc.getDim(ijk, ray));
206 if (hdda.
dim() > 1 || !acc.isActive(ijk))
208 while (hdda.
step() && acc.isActive(hdda.
voxel())) {
209 v = acc.getValue(hdda.
voxel());
222template<
typename RayT,
typename AccT>
223inline __hostdev__ bool isoCrossing(RayT& ray, AccT& acc,
Coord& ijk,
typename AccT::ValueType& v,
float& t,
const typename AccT::ValueType& iso = 0.0f)
226 if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20)
return false;
227 static const float Delta = 1.0001f;
230 const auto v0 = acc.getValue(ijk) - iso;
231 while (hdda.
step()) {
233 hdda.
update(ray, acc.getDim(ijk, ray));
234 if (hdda.
dim() > 1 || !acc.isActive(ijk))
continue;
235 while (hdda.
step() && acc.isActive(hdda.
voxel())) {
236 v = acc.getValue(hdda.
voxel()) - iso;
255template<
typename RayT,
typename CoordT = Coord,
int Dim = 1>
258 static_assert(Dim >= 1,
"Dim must be >= 1");
279 const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
281 for (
int axis = 0; axis < 3; ++axis) {
282 if (dir[axis] ==
RealT(0)) {
285 }
else if (inv[axis] > 0) {
287 mNext[axis] = (mT0 + (
RealT(mVoxel[axis] + Dim) - pos[axis]) * inv[axis]);
288 mDelta[axis] = inv[axis];
291 mNext[axis] = mT0 + (
RealT(mVoxel[axis]) - pos[axis]) * inv[axis];
292 mDelta[axis] = -inv[axis];
315#ifdef ENFORCE_FORWARD_STEPPING
316 if (mNext[axis] <= mT0) {
317 mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6f;
321 mNext[axis] += mDelta[axis];
322 mVoxel[axis] += mStep[axis];
349 return Min(mT1,
Min(mNext[0],
Min(mNext[1], mNext[2])));
362#ifdef ENFORCE_FORWARD_STEPPING
363 if (mNext[axis] <= mT0) {
364 mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6f;
368 mNext[axis] += mDelta[axis];
369 mVoxel[axis] += mStep[axis];
374 CoordT mVoxel, mStep;
380template<
typename RayT,
typename NodeT>
385 if (!ray.clip(node.bbox())) {
389 const float t0 = ray.t0();
391 static const float Delta = 1.0001f;
401 if (bbox.isInside(ijk) ==
false)
404 v = node.getValue(ijk);
419template<
typename RayT,
typename AccT>
422 if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20) {
425 static const float Delta = 1.0001f;
428 for (
HDDA<RayT, Coord> hdda(ray, acc.getDim(ijk, ray)); !acc.isActive(ijk); hdda.
update(ray, acc.getDim(ijk, ray))) {
429 if (!hdda.step())
return false;
430 t = hdda.time() +
Delta;
440template<
typename NodeT,
typename RayT,
typename AccT,
typename CoordT = Coord>
444 using ChildT =
typename NodeT::ChildNodeType;
458 if (!mRay.clip(mAcc.root().bbox()))
463 static const float Eps = 0.000001f;
464 const float t0 = mRay.t0() + Eps;
465 const float t1 = mRay.t1() - Eps;
470 const uint32_t dim = mAcc.getDim(ijk, mRay);
473 mT0 = (dim <= ChildT::dim()) ? mHdda.time() : -1;
485 static const float Delta = 0.01f;
491 auto currentNode = mAcc.template getNode<NodeT>();
494 hddaIsValid = mHdda.step();
496 const auto nextDim = mAcc.getDim(nextIjk, mRay);
497 mHdda.update(mRay, (
int)
Max(nextDim, NodeT::dim()));
498 mT0 = (nextDim <= ChildT::dim()) ? mHdda.time() : -1;
501 t1 =
Min(mTmax, mHdda.time());
504 if (t0 >= t1 || currentNode ==
nullptr)
511 }
while (hddaIsValid);
535template<
typename AccT,
typename RayT,
typename CoordT = Coord>
Implements a light-weight self-contained VDB data-structure in a single file! In other words,...
#define __hostdev__
Definition SampleFromVoxels.h:29
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition Math.h:425
static __hostdev__ Coord Floor(const Vec3T &xyz) noexcept
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition Math.h:663
A Digital Differential Analyzer. Unlike HDDA (defined above) this DDA uses a fixed step-size defined ...
Definition HDDA.h:257
__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:332
CoordT CoordType
Definition HDDA.h:265
__hostdev__ RealType maxTime() const
Return the maximum time (parameterized along the Ray).
Definition HDDA.h:342
__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:339
__hostdev__ int nextAxis() const
Definition HDDA.h:352
__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:347
__hostdev__ DDA(const RayT &ray)
ctor from ray and dimension at which the DDA marches
Definition HDDA.h:271
__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:302
DDA()=default
Default ctor.
RealType RealT
Definition HDDA.h:262
Vec3Type Vec3T
Definition HDDA.h:264
__hostdev__ void init(const RayT &ray)
Simular to init above except it uses the bounds of the input ray.
Definition HDDA.h:298
__hostdev__ void init(const RayT &ray, RealT startTime, RealT maxTime)
Re-initializes the DDA.
Definition HDDA.h:274
typename RayT::Vec3Type Vec3Type
Definition HDDA.h:263
typename RayT::RealType RealType
Definition HDDA.h:261
A Digital Differential Analyzer specialized for OpenVDB grids.
Definition HDDA.h:34
__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:138
CoordT CoordType
Definition HDDA.h:40
__hostdev__ RealType maxTime() const
Return the maximum time (parameterized along the Ray).
Definition HDDA.h:148
__hostdev__ void init(const RayT &ray, int dim)
Simular to init above except it uses the bounds of the input ray.
Definition HDDA.h:74
__hostdev__ HDDA(const RayT &ray, int dim)
ctor from ray and dimension at which the DDA marches
Definition HDDA.h:46
__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:145
__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:153
__hostdev__ void init(const RayT &ray, RealT startTime, RealT maxTime, int dim)
Re-initializes the HDDA.
Definition HDDA.h:49
__hostdev__ int dim() const
Definition HDDA.h:109
__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:113
RealType RealT
Definition HDDA.h:37
Vec3Type Vec3T
Definition HDDA.h:39
typename RayT::Vec3Type Vec3Type
Definition HDDA.h:38
HDDA()=default
Default ctor.
typename RayT::RealType RealType
Definition HDDA.h:36
__hostdev__ bool update(const RayT &ray, int dim)
Updates the HDDA to march with the specified dimension.
Definition HDDA.h:77
__hostdev__ PointTreeMarcher(AccT &acc)
Definition HDDA.h:540
__hostdev__ bool init(RayT ray)
Initiates this instance with a ray in index space.
Definition HDDA.h:551
CoordT CoordType
Definition HDDA.h:447
__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:481
__hostdev__ const RayT & ray() const
Definition HDDA.h:516
typename NodeT::ChildNodeType ChildT
Definition HDDA.h:444
__hostdev__ RayT & ray()
Definition HDDA.h:518
RealType RealT
Definition HDDA.h:446
__hostdev__ bool init(const RayT &indexRay)
Initialize the TreeMarcher with an index-space ray.
Definition HDDA.h:455
__hostdev__ TreeMarcher(AccT &acc)
Definition HDDA.h:449
typename RayT::RealType RealType
Definition HDDA.h:445
Definition DitherLUT.h:19
__hostdev__ CoordT RoundDown(const Vec3T< RealT > &xyz) noexcept
Round each component of xyz down (toward -inf) into a CoordT.
Definition Math.h:345
__hostdev__ constexpr Type Max(Type a, Type b) noexcept
Same-type maximum (the primary template).
Definition Math.h:187
__hostdev__ constexpr int MinIndex(const Vec3T &v) noexcept
Return the component index (0, 1, or 2) of the smallest element of v.
Definition Math.h:372
__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:223
__hostdev__ bool zeroCrossingNode(RayT &ray, const NodeT &node, float v0, nanovdb::math::Coord &ijk, float &v, float &t)
Definition HDDA.h:381
__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:420
__hostdev__ constexpr Type Min(Type a, Type b) noexcept
Same-type minimum (the primary template).
Definition Math.h:161
__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:194
Per-type small floating-point offset, useful for nudging boundaries off-edge in geometric tests.
Definition Math.h:88
static constexpr T value() noexcept
Definition Math.h:147
static constexpr bool value
Definition Util.h:375