10 #ifndef NANOVDB_HDDA_H_HAS_BEEN_INCLUDED 
   11 #define NANOVDB_HDDA_H_HAS_BEEN_INCLUDED 
   14 #define ENFORCE_FORWARD_STEPPING 
   28 template<
typename RayT, 
typename CoordT = Coord>
 
   47         assert(startTime <= maxTime);
 
   51         const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
 
   52         mVoxel = RoundDown<CoordT>(pos) & (~(dim - 1));
 
   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];
 
   78         const Vec3T &pos = ray(mT0), &inv = ray.invDir();
 
   79         mVoxel = RoundDown<CoordT>(pos) & (~(dim - 1));
 
   80         for (
int axis = 0; axis < 3; ++axis) {
 
   83             mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
 
   85                 mNext[axis] += dim * inv[axis];
 
  109         mNext[axis] += mDim * mDelta[axis];
 
  110         mVoxel[axis] += mDim * mStep[axis];
 
  137 #if 1 //def __CUDA_ARCH__ 
  138         return fminf(mT1, fminf(mNext[0], fminf(mNext[1], mNext[2])));
 
  149 #ifdef ENFORCE_FORWARD_STEPPING 
  152         if (mNext[axis] <= mT0) {
 
  153             mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6
f;
 
  157         mNext[ axis] += mDim * mDelta[axis];
 
  158         mVoxel[axis] += mDim * mStep[ axis];
 
  164     CoordT  mVoxel, mStep; 
 
  175 template<
typename RayT, 
typename AccT>
 
  178     if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20)
 
  180     static const float Delta = 1.0001f;
 
  181     ijk = RoundDown<Coord>(ray.start()); 
 
  183     const auto        v0 = acc.getValue(ijk);
 
  184     while (hdda.step()) {
 
  185         ijk = RoundDown<Coord>(ray(hdda.time() + Delta));
 
  186         hdda.update(ray, acc.getDim(ijk, ray));
 
  187         if (hdda.dim() > 1 || !acc.isActive(ijk))
 
  189         while (hdda.step() && acc.isActive(hdda.voxel())) { 
 
  190             v = acc.getValue(hdda.voxel());
 
  209 template<
typename RayT, 
typename CoordT = Coord, 
int Dim = 1>
 
  212     static_assert(Dim >= 1, 
"Dim must be >= 1");
 
  230         assert(startTime <= maxTime);
 
  233         const Vec3T &pos = ray(mT0), &dir = ray.dir(), &inv = ray.invDir();
 
  234         mVoxel = RoundDown<CoordT>(pos) & (~(Dim - 1));
 
  235         for (
int axis = 0; axis < 3; ++axis) {
 
  236             if (dir[axis] == 
RealT(0)) { 
 
  239             } 
else if (inv[axis] > 0) {
 
  241                 mNext[axis] = (mT0 + (mVoxel[axis] + Dim - pos[axis]) * inv[axis]);
 
  242                 mDelta[axis] = inv[axis];
 
  245                 mNext[axis] = mT0 + (mVoxel[axis] - pos[axis]) * inv[axis];
 
  246                 mDelta[axis] = -inv[axis];
 
  269 #ifdef ENFORCE_FORWARD_STEPPING 
  270         if (mNext[axis] <= mT0) {
 
  271             mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6
f;
 
  275         mNext[axis] += mDelta[axis];
 
  276         mVoxel[axis] += mStep[axis];
 
  303         return Min(mT1, 
Min(mNext[0], 
Min(mNext[1], mNext[2])));
 
  316 #ifdef ENFORCE_FORWARD_STEPPING 
  317         if (mNext[axis] <= mT0) {
 
  318             mNext[axis] += mT0 - 0.999999f * mNext[axis] + 1.0e-6
f;
 
  322         mNext[axis] += mDelta[axis];
 
  323         mVoxel[axis] += mStep[axis];
 
  328     CoordT mVoxel, mStep; 
 
  334 template<
typename RayT, 
typename NodeT>
 
  339     if (!ray.clip(node.bbox())) {
 
  343     const float t0 = ray.t0();
 
  345     static const float Delta = 1.0001f;
 
  355         if (bbox.isInside(ijk) == 
false)
 
  358         v = node.getValue(ijk);
 
  373 template<
typename RayT, 
typename AccT>
 
  376     if (!ray.clip(acc.root().bbox()) || ray.t1() > 1e20) {
 
  379     static const float Delta = 1.0001f;
 
  381     ijk = RoundDown<Coord>(ray.start()); 
 
  382     for (
HDDA<RayT, Coord> hdda(ray, acc.getDim(ijk, ray)); !acc.isActive(ijk); hdda.
update(ray, acc.getDim(ijk, ray))) {
 
  383         if (!hdda.step()) 
return false;
 
  384         t = hdda.time() + Delta;
 
  385         ijk = RoundDown<Coord>( ray(t) );
 
  394 template<
typename NodeT, 
typename RayT, 
typename AccT, 
typename CoordT = Coord>
 
  398     using ChildT = 
typename NodeT::ChildNodeType;
 
  412         if (!mRay.clip(mAcc.root().bbox()))
 
  417         static const float Eps = 0.000001f;
 
  418         const float        t0 = mRay.t0() + Eps;
 
  419         const float        t1 = mRay.t1() - Eps;
 
  423         const CoordT ijk = RoundDown<Coord>(mRay(t0));
 
  424         const uint32_t    dim = mAcc.getDim(ijk, mRay);
 
  425         mHdda.init(mRay, t0, t1, 
nanovdb::Max(dim, NodeT::dim()));
 
  427         mT0 = (dim <= ChildT::dim()) ? mHdda.time() : -1; 
 
  439         static const float Delta = 0.01f;
 
  445             auto currentNode = mAcc.template getNode<NodeT>();
 
  448             hddaIsValid = mHdda.step();
 
  449             const CoordT nextIjk = RoundDown<Coord>(mRay(mHdda.time() + Delta));
 
  450             const auto   nextDim = mAcc.getDim(nextIjk, mRay);
 
  451             mHdda.update(mRay, (
int)
Max(nextDim, NodeT::dim()));
 
  452             mT0 = (nextDim <= ChildT::dim()) ? mHdda.time() : -1; 
 
  455                 t1 = 
Min(mTmax, mHdda.time());
 
  458                 if (t0 >= t1 || currentNode == 
nullptr)
 
  465         } 
while (hddaIsValid);
 
  489 template<
typename AccT, 
typename RayT, 
typename CoordT = Coord>
 
  510 #endif // NANOVDB_HDDA_HAS_BEEN_INCLUDED 
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord. 
 
__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...
 
__hostdev__ RealType maxTime() const 
Return the maximum time (parameterized along the Ray). 
 
__hostdev__ bool init(const RayT &indexRay)
Initialize the TreeMarcher with an index-space ray. 
 
__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...
 
A Digital Differential Analyzer. Unlike HDDA (defined above) this DDA uses a fixed step-size defined ...
 
__hostdev__ void init(const RayT &ray)
Simular to init above except it uses the bounds of the input ray. 
 
typename LeafNode< AccT::ValueType >::ChildNodeType ChildT
 
__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...
 
__hostdev__ bool step()
Increment the voxel index to next intersected voxel or node and returns true if the step in time does...
 
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
 
typename RayT::RealType RealType
 
__hostdev__ PointTreeMarcher(AccT &acc)
 
__hostdev__ const RayT & ray() const 
 
__hostdev__ RealType time() const 
Return the time (parameterized along the Ray) of the first hit of a tree node of size 2^Log2Dim...
 
__hostdev__ Type Min(Type a, Type b)
 
HDDA()=default
Default ctor. 
 
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
 
__hostdev__ HDDA(const RayT &ray, int dim)
ctor from ray and dimension at which the DDA marches 
 
__hostdev__ const CoordT & voxel() const 
Return the index coordinates of the next node or voxel intersected by the ray. If Log2Dim = 0 the ret...
 
__hostdev__ bool step()
Increment the voxel index to next intersected voxel or node and returns true if the step in time does...
 
typename RayT::RealType RealType
 
__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^...
 
typename RayT::Vec3Type Vec3Type
 
__hostdev__ bool init(RayT ray)
Initiates this instance with a ray in index space. 
 
__hostdev__ bool ZeroCrossingNode(RayT &ray, const NodeT &node, float v0, nanovdb::Coord &ijk, float &v, float &t)
 
A Digital Differential Analyzer specialized for OpenVDB grids. 
 
__hostdev__ RealType time() const 
Return the time (parameterized along the Ray) of the first hit of a tree node of size 2^Log2Dim...
 
__hostdev__ int MinIndex(const Vec3T &v)
 
DDA()=default
Default ctor. 
 
__hostdev__ DDA(const RayT &ray)
ctor from ray and dimension at which the DDA marches 
 
__hostdev__ int dim() const 
 
__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^...
 
__hostdev__ bool update(const RayT &ray, int dim)
Updates the HDDA to march with the specified dimension. 
 
__hostdev__ Type Max(Type a, Type b)
 
__hostdev__ TreeMarcher(AccT &acc)
 
Delta for small floating-point offsets. 
 
__hostdev__ RealType maxTime() const 
Return the maximum time (parameterized along the Ray). 
 
__hostdev__ void init(const RayT &ray, int dim)
Simular to init above except it uses the bounds of the input ray. 
 
A Tree Marcher for Generic Grids. 
 
__hostdev__ void init(const RayT &ray, RealT startTime, RealT maxTime)
Re-initializes the DDA. 
 
static __hostdev__ Coord Floor(const Vec3T &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion)...
 
__hostdev__ int nextAxis() const 
 
__hostdev__ void init(const RayT &ray, RealT startTime, RealT maxTime, int dim)
Re-initializes the HDDA. 
 
__hostdev__ const CoordT & voxel() const 
Return the index coordinates of the next node or voxel intersected by the ray. If Log2Dim = 0 the ret...
 
typename RayT::Vec3Type Vec3Type
 
typename RayT::RealType RealType
 
A Tree Marcher for Point Grids.