From 0df8984126b0c9a440fcb33ccb8580c268b9c76c Mon Sep 17 00:00:00 2001 From: Lukas Werner <lks.werner@fau.de> Date: Thu, 8 Mar 2018 21:35:55 +0100 Subject: [PATCH] Added early cutoff for intersection testing in hashgrids --- src/pe/ccd/HashGrids.h | 60 +++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/src/pe/ccd/HashGrids.h b/src/pe/ccd/HashGrids.h index e6fd5cdef..14dc612ca 100644 --- a/src/pe/ccd/HashGrids.h +++ b/src/pe/ccd/HashGrids.h @@ -527,13 +527,10 @@ const BodyID HashGrids::HashGrid::getBodyIntersectionForBlockCell(const Vector3< real_t x = (real_c(blockCell[0]) + real_t(0.5)) * cellSpan_; real_t y = (real_c(blockCell[1]) + real_t(0.5)) * cellSpan_; real_t z = (real_c(blockCell[2]) + real_t(0.5)) * cellSpan_; - + // hash of cell in the hashgrid size_t cellHash = hashPoint(x, y, z); - //WALBERLA_LOG_INFO("cell " << cellHash); - //WALBERLA_LOG_INFO(" normal axis: " << int(cellNormalAxis) << ", dir: " << int(cellNormalDir)); - const Cell& centerCell = cell_[cellHash]; std::vector<offset_t> relevantNeighborIndices; @@ -582,7 +579,6 @@ const BodyID HashGrids::HashGrid::getBodyIntersectionForBlockCell(const Vector3< body = cellBody; t_closest = t_local; n_closest = n_local; - //WALBERLA_LOG_INFO(" found body " << body->getID() << " in " << neighborIndex << " (" << (int(cellHash)+centerCell.neighborOffset_[neighborIndex]) << ")"); } } } @@ -617,10 +613,9 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c int32_t blockYCellCountMax = int32_c(std::ceil(blockAABB.yMax() * inverseCellSpan_)) + 1; int32_t blockZCellCountMin = int32_c(blockAABB.zMin() * inverseCellSpan_) - 1; int32_t blockZCellCountMax = int32_c(std::ceil(blockAABB.zMax() * inverseCellSpan_)) + 1; - - //WALBERLA_LOG_INFO("cellspan: " << cellSpan_ << " lims: " << blockXCellCountMin << " " << blockXCellCountMax); Vec3 firstPoint; + real_t tRayOriginToGrid = 0; if (blockAABB.contains(ray.getOrigin(), cellSpan_)) { firstPoint = ray.getOrigin(); } else { @@ -629,8 +624,8 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c if (intersects(blockAABB, ray, t_start, cellSpan_, &firstPointNormal)) { firstPoint = ray.getOrigin() + ray.getDirection()*t_start; firstPoint -= firstPointNormal * (cellSpan_/real_t(2)); + tRayOriginToGrid = (ray.getOrigin() - firstPoint).length(); } else { - //WALBERLA_LOG_INFO("ray does not intersect block") return NULL; } } @@ -647,10 +642,12 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c (stepY >= 0) ? (firstCell[1]+1)*cellSpan_-firstPoint[1] : firstPoint[1]-firstCell[1]*cellSpan_, (stepZ >= 0) ? (firstCell[2]+1)*cellSpan_-firstPoint[2] : firstPoint[2]-firstCell[2]*cellSpan_); + // tMax: distance along the ray to the next cell change in the axis direction real_t tMaxX = (ray.xDir() != 0) ? std::abs(near[0]*ray.xInvDir()) : inf; real_t tMaxY = (ray.yDir() != 0) ? std::abs(near[1]*ray.yInvDir()) : inf; real_t tMaxZ = (ray.zDir() != 0) ? std::abs(near[2]*ray.zInvDir()) : inf; + // tDelta: how far along the ray must be moved to encounter a new cell in the specified axis direction real_t tDeltaX = (ray.xDir() != 0) ? std::abs(cellSpan_*ray.xInvDir()) : inf; real_t tDeltaY = (ray.yDir() != 0) ? std::abs(cellSpan_*ray.yInvDir()) : inf; real_t tDeltaZ = (ray.zDir() != 0) ? std::abs(cellSpan_*ray.zInvDir()) : inf; @@ -674,9 +671,17 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c int8_t blockCellNormalAxis; int8_t blockCellNormalDir; + static int earlyCutoffs = 0; + while (true) { if (tMaxX < tMaxY) { if (tMaxX < tMaxZ) { +#if !defined(HASHGRIDS_DISABLE_EARLY_CUTOFF) + if (tRayOriginToGrid+tMaxX-tDeltaX > t_closest) { + earlyCutoffs++; + break; + } +#endif tMaxX += tDeltaX; currentCell[0] += stepX; blockCellNormalAxis = 0; @@ -685,6 +690,12 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c break; } } else { +#if !defined(HASHGRIDS_DISABLE_EARLY_CUTOFF) + if (tRayOriginToGrid+tMaxZ-tDeltaZ > t_closest) { + earlyCutoffs++; + break; + } +#endif tMaxZ += tDeltaZ; currentCell[2] += stepZ; blockCellNormalAxis = 2; @@ -695,6 +706,12 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c } } else { if (tMaxY < tMaxZ) { +#if !defined(HASHGRIDS_DISABLE_EARLY_CUTOFF) + if (tRayOriginToGrid+tMaxY-tDeltaY > t_closest) { + earlyCutoffs++; + break; + } +#endif tMaxY += tDeltaY; currentCell[1] += stepY; blockCellNormalAxis = 1; @@ -703,6 +720,12 @@ BodyID HashGrids::HashGrid::getRayIntersectingBody(const raytracing::Ray& ray, c break; } } else { +#if !defined(HASHGRIDS_DISABLE_EARLY_CUTOFF) + if (tRayOriginToGrid+tMaxZ-tDeltaZ > t_closest) { + earlyCutoffs++; + break; + } +#endif tMaxZ += tDeltaZ; currentCell[2] += stepZ; blockCellNormalAxis = 2; @@ -745,13 +768,6 @@ BodyID HashGrids::getClosestBodyIntersectingWithRay(const raytracing::Ray& ray, real_t t_local = inf; Vec3 n_local; - for(auto grid: gridList_) { - body_local = grid->getRayIntersectingBody<BodyTuple>(ray, blockAABB, t_closest, n_closest); - if (body_local != NULL){ - body_closest = body_local; - } - } - raytracing::IntersectsFunctor intersectsFunc(ray, t_local, n_local); for(auto body: nonGridBodies_) { bool intersects = SingleCast<BodyTuple, raytracing::IntersectsFunctor, bool>::execute(body, intersectsFunc); @@ -762,6 +778,20 @@ BodyID HashGrids::getClosestBodyIntersectingWithRay(const raytracing::Ray& ray, } } + for (auto gridIt = gridList_.rbegin(); gridIt != gridList_.rend(); ++gridIt) { + body_local = (*gridIt)->getRayIntersectingBody<BodyTuple>(ray, blockAABB, t_closest, n_closest); + if (body_local != NULL){ + body_closest = body_local; + } + } + + /*for(auto grid: gridList_) { + body_local = grid->getRayIntersectingBody<BodyTuple>(ray, blockAABB, t_closest, n_closest); + if (body_local != NULL){ + body_closest = body_local; + } + }*/ + t = t_closest; n = n_closest; -- GitLab