1// Copyright 2020-2021 Intel Corporation 2// SPDX-License-Identifier: Apache-2.0 3 4#pragma once 5 6// --------------------------------------------------------------------------- 7// Step through a DDA hierarchy. 8// 9// Note: We generate files HDDA_level>.ih from this 10// template using CMake. 11// --------------------------------------------------------------------------- 12 13#if (@VKL_VDB_NEXT_LEVEL@) < VKL_VDB_NUM_LEVELS 14 #include "HDDA_@VKL_VDB_NEXT_LEVEL@.ih" 15#endif 16 17/* 18 * Step once in the hierarchy. 19 * This potentially steps once on each level. 20 * 21 * Precondition: desc points to a voxel on some level. The goal 22 * of hddaStep is to leave this voxel. 23 */ 24#if @VKL_VDB_LEVEL@ == 0 25void hddaStep(const VdbGrid *uniform grid, 26 const VdbVoxelDescriptor &desc, 27 DdaState &dda) 28{ 29#else 30bool hddaStep_@VKL_VDB_LEVEL@(const VdbGrid *uniform grid, 31 const VdbVoxelDescriptor &desc, 32 DdaState &dda) 33{ 34#endif 35 36 // We traverse depth-first to step on the lowest level possible. 37 const bool lowestLevel = (desc.level == @VKL_VDB_LEVEL@); 38 bool stepped = false; 39 40 // First case: we can potentially descend to the next level. 41#if @VKL_VDB_NEXT_LEVEL@ < @VKL_VDB_NUM_LEVELS@ 42 const uniform uint32 ox = DDA_STATE_X_OFFSET(@VKL_VDB_LEVEL@); 43 const uniform uint32 oy = DDA_STATE_Y_OFFSET(@VKL_VDB_LEVEL@); 44 const uniform uint32 oz = DDA_STATE_Z_OFFSET(@VKL_VDB_LEVEL@); 45 if (lowestLevel) 46 { 47 const int32 oldx = dda.idx[ox]; 48 const int32 oldy = dda.idx[oy]; 49 const int32 oldz = dda.idx[oz]; 50 ddaStep(dda, @VKL_VDB_LEVEL@); 51 stepped = true; 52 53 if (@VKL_VDB_LEVEL@ < dda.level) 54 { 55 // We are on the same level as the voxel described by desc, 56 // but that is NOT the lowest level dda state. 57 // Reinitialize the lower levels to keep them consistent. 58 // This keeps the dda state consistent towards the leaf level. 59 // If this level moved in x-dimension, then all lower levels 60 // will move by the same amount in x-dimension. y and z must be 61 // recomputed, however, as must tNext for x and y. 62 const int32 dx = dda.idx[ox]-oldx; 63 const int32 dy = dda.idx[oy]-oldy; 64 const int32 dz = dda.idx[oz]-oldz; 65 ddaReinitBelow(dda, @VKL_VDB_LEVEL@, dx, dy, dz); 66 } 67 } 68 else 69 { 70 if (hddaStep_@VKL_VDB_NEXT_LEVEL@(grid, desc, dda)) 71 { 72 // We check if the child has left our domain and follow it if it has. 73 // This keeps the dda state consistent towards the root node. 74 const uniform int32 cellRes = VKL_VDB_RES_@VKL_VDB_NEXT_LEVEL@; 75 const uniform uint32 cox = DDA_STATE_X_OFFSET(@VKL_VDB_NEXT_LEVEL@); 76 const uniform uint32 coy = DDA_STATE_Y_OFFSET(@VKL_VDB_NEXT_LEVEL@); 77 const uniform uint32 coz = DDA_STATE_Z_OFFSET(@VKL_VDB_NEXT_LEVEL@); 78 const bool childHasLeftDomain = dda.idx[cox] < dda.idx[ox] 79 || dda.idx[coy] < dda.idx[oy] 80 || dda.idx[coz] < dda.idx[oz] 81 || dda.idx[cox] >= (dda.idx[ox] + cellRes) 82 || dda.idx[coy] >= (dda.idx[oy] + cellRes) 83 || dda.idx[coz] >= (dda.idx[oz] + cellRes); 84 if (childHasLeftDomain) { 85 ddaStep(dda, @VKL_VDB_LEVEL@); 86 stepped = true; 87 } 88 } 89 } 90 91 // Second case: We cannot descend because there is no next level. 92#else // @VKL_VDB_NEXT_LEVEL@ < @VKL_VDB_NUM_LEVELS@ 93 assert(lowestLevel); 94 ddaStep(dda, @VKL_VDB_LEVEL@); 95 stepped = true; 96#endif 97 98#if @VKL_VDB_LEVEL@ > 0 99 return stepped; 100#endif 101} 102