public void intersect(Ray r, IntersectionState state) { float intervalMin = r.getMin(); float intervalMax = r.getMax(); float orgX = r.ox; float dirX = r.dx, invDirX = 1 / dirX; float t1, t2; t1 = (bounds.getMinimum().x - orgX) * invDirX; t2 = (bounds.getMaximum().x - orgX) * invDirX; if (invDirX > 0) { if (t1 > intervalMin) { intervalMin = t1; } if (t2 < intervalMax) { intervalMax = t2; } } else { if (t2 > intervalMin) { intervalMin = t2; } if (t1 < intervalMax) { intervalMax = t1; } } if (intervalMin > intervalMax) { return; } float orgY = r.oy; float dirY = r.dy, invDirY = 1 / dirY; t1 = (bounds.getMinimum().y - orgY) * invDirY; t2 = (bounds.getMaximum().y - orgY) * invDirY; if (invDirY > 0) { if (t1 > intervalMin) { intervalMin = t1; } if (t2 < intervalMax) { intervalMax = t2; } } else { if (t2 > intervalMin) { intervalMin = t2; } if (t1 < intervalMax) { intervalMax = t1; } } if (intervalMin > intervalMax) { return; } float orgZ = r.oz; float dirZ = r.dz, invDirZ = 1 / dirZ; t1 = (bounds.getMinimum().z - orgZ) * invDirZ; t2 = (bounds.getMaximum().z - orgZ) * invDirZ; if (invDirZ > 0) { if (t1 > intervalMin) { intervalMin = t1; } if (t2 < intervalMax) { intervalMax = t2; } } else { if (t2 > intervalMin) { intervalMin = t2; } if (t1 < intervalMax) { intervalMax = t1; } } if (intervalMin > intervalMax) { return; } // box is hit at [intervalMin, intervalMax] orgX += intervalMin * dirX; orgY += intervalMin * dirY; orgZ += intervalMin * dirZ; // locate starting point inside the grid // and set up 3D-DDA vars int indxX, indxY, indxZ; int stepX, stepY, stepZ; int stopX, stopY, stopZ; float deltaX, deltaY, deltaZ; float tnextX, tnextY, tnextZ; // stepping factors along X indxX = (int)((orgX - bounds.getMinimum().x) * invVoxelwx); if (indxX < 0) { indxX = 0; } else if (indxX >= nx) { indxX = nx - 1; } if (Math.Abs(dirX) < 1e-6f) { stepX = 0; stopX = indxX; deltaX = 0; tnextX = float.PositiveInfinity; } else if (dirX > 0) { stepX = 1; stopX = nx; deltaX = voxelwx * invDirX; tnextX = intervalMin + ((indxX + 1) * voxelwx + bounds.getMinimum().x - orgX) * invDirX; } else { stepX = -1; stopX = -1; deltaX = -voxelwx * invDirX; tnextX = intervalMin + (indxX * voxelwx + bounds.getMinimum().x - orgX) * invDirX; } // stepping factors along Y indxY = (int)((orgY - bounds.getMinimum().y) * invVoxelwy); if (indxY < 0) { indxY = 0; } else if (indxY >= ny) { indxY = ny - 1; } if (Math.Abs(dirY) < 1e-6f) { stepY = 0; stopY = indxY; deltaY = 0; tnextY = float.PositiveInfinity; } else if (dirY > 0) { stepY = 1; stopY = ny; deltaY = voxelwy * invDirY; tnextY = intervalMin + ((indxY + 1) * voxelwy + bounds.getMinimum().y - orgY) * invDirY; } else { stepY = -1; stopY = -1; deltaY = -voxelwy * invDirY; tnextY = intervalMin + (indxY * voxelwy + bounds.getMinimum().y - orgY) * invDirY; } // stepping factors along Z indxZ = (int)((orgZ - bounds.getMinimum().z) * invVoxelwz); if (indxZ < 0) { indxZ = 0; } else if (indxZ >= nz) { indxZ = nz - 1; } if (Math.Abs(dirZ) < 1e-6f) { stepZ = 0; stopZ = indxZ; deltaZ = 0; tnextZ = float.PositiveInfinity; } else if (dirZ > 0) { stepZ = 1; stopZ = nz; deltaZ = voxelwz * invDirZ; tnextZ = intervalMin + ((indxZ + 1) * voxelwz + bounds.getMinimum().z - orgZ) * invDirZ; } else { stepZ = -1; stopZ = -1; deltaZ = -voxelwz * invDirZ; tnextZ = intervalMin + (indxZ * voxelwz + bounds.getMinimum().z - orgZ) * invDirZ; } int cellstepX = stepX; int cellstepY = stepY * nx; int cellstepZ = stepZ * ny * nx; int cell = indxX + indxY * nx + indxZ * ny * nx; // trace through the grid for (; ;) { if (tnextX < tnextY && tnextX < tnextZ) { if (cells[cell] != null) { foreach (int i in cells[cell]) { primitives.intersectPrimitive(r, i, state); } if (state.hit() && (r.getMax() < tnextX && r.getMax() < intervalMax)) { return; } } intervalMin = tnextX; if (intervalMin > intervalMax) { return; } indxX += stepX; if (indxX == stopX) { return; } tnextX += deltaX; cell += cellstepX; } else if (tnextY < tnextZ) { if (cells[cell] != null) { foreach (int i in cells[cell]) { primitives.intersectPrimitive(r, i, state); } if (state.hit() && (r.getMax() < tnextY && r.getMax() < intervalMax)) { return; } } intervalMin = tnextY; if (intervalMin > intervalMax) { return; } indxY += stepY; if (indxY == stopY) { return; } tnextY += deltaY; cell += cellstepY; } else { if (cells[cell] != null) { foreach (int i in cells[cell]) { primitives.intersectPrimitive(r, i, state); } if (state.hit() && (r.getMax() < tnextZ && r.getMax() < intervalMax)) { return; } } intervalMin = tnextZ; if (intervalMin > intervalMax) { return; } indxZ += stepZ; if (indxZ == stopZ) { return; } tnextZ += deltaZ; cell += cellstepZ; } } }