public override bool Intersect(Ray ray) { float rayT = 0, t = 0; if (_bbox.Inside(ray.PointAtTime(ray.Start))) { rayT = ray.Start; } else if (!_bbox.IntersectP(ray, ref rayT, ref t)) { return(false); } var gridIntersect = ray.PointAtTime(rayT); float[] nextCrossingT = new float[3], deltaT = new float[3]; int[] step = new int[3], _out = new int[3], pos = new int[3]; pos[0] = PosToVoxel(gridIntersect, 0); pos[1] = PosToVoxel(gridIntersect, 1); pos[2] = PosToVoxel(gridIntersect, 2); if (ray.Direction.X >= 0) { nextCrossingT[0] = rayT + (VoxelToPos(pos[0] + 1, 0) - gridIntersect.X) / ray.Direction.X; deltaT[0] = _width[0] / ray.Direction.X; step[0] = 1; _out[0] = _nVoxels[0]; } else { nextCrossingT[0] = rayT + (VoxelToPos(pos[0], 0) - gridIntersect.X) / ray.Direction.X; deltaT[0] = -_width[0] / ray.Direction.X; step[0] = -1; _out[0] = -1; } if (ray.Direction.Y >= 0) { nextCrossingT[1] = rayT + (VoxelToPos(pos[1] + 1, 1) - gridIntersect.Y) / ray.Direction.Y; deltaT[1] = _width[1] / ray.Direction.Y; step[1] = 1; _out[1] = _nVoxels[1]; } else { nextCrossingT[1] = rayT + (VoxelToPos(pos[1], 1) - gridIntersect.Y) / ray.Direction.Y; deltaT[1] = -_width[1] / ray.Direction.Y; step[1] = -1; _out[1] = -1; } if (ray.Direction.Z >= 0) { nextCrossingT[2] = rayT + (VoxelToPos(pos[2] + 1, 2) - gridIntersect.Z) / ray.Direction.Z; deltaT[2] = _width[2] / ray.Direction.Z; step[2] = 1; _out[2] = _nVoxels[2]; } else { nextCrossingT[2] = rayT + (VoxelToPos(pos[2], 2) - gridIntersect.Z) / ray.Direction.Z; deltaT[2] = -_width[2] / ray.Direction.Z; step[2] = -1; _out[2] = -1; } for (; ;) { var voxel = _voxels[Offset(pos[0], pos[1], pos[2])]; if (voxel != null) { if (voxel.Intersect(ray)) { return(true); } } var bits = (((nextCrossingT[0] < nextCrossingT[1]) ? 1 : 0) << 2) + (((nextCrossingT[0] < nextCrossingT[2]) ? 1 : 0) << 1) + (((nextCrossingT[1] < nextCrossingT[2]) ? 1 : 0)); var stepAxis = _cmpToAxis[bits]; if (ray.End < nextCrossingT[stepAxis]) { break; } pos[stepAxis] += step[stepAxis]; if (pos[stepAxis] == _out[stepAxis]) { break; } nextCrossingT[stepAxis] += deltaT[stepAxis]; } return(false); }
public override bool Intersect(Ray ray) { float rayT = 0, t = 0; if (_bbox.Inside(ray.PointAtTime(ray.Start))) { rayT = ray.Start; } else if (!_bbox.IntersectP(ray, ref rayT, ref t)) { return(false); } var gridIntersect = ray.PointAtTime(rayT); float[] nextCrossingT = new float[3], deltaT = new float[3]; int[] step = new int[3], _out = new int[3], pos = new int[3]; for (var i = 0; i < 3; i++) { pos[i] = PosToVoxel(gridIntersect, i); if (ray.Direction[i] >= 0) { nextCrossingT[i] = rayT + (VoxelToPos(pos[i] + 1, i) - gridIntersect[i]) / ray.Direction[i]; deltaT[i] = _width[i] / ray.Direction[i]; step[i] = 1; _out[i] = _nVoxels[i]; } else { nextCrossingT[i] = rayT + (VoxelToPos(pos[i], i) - gridIntersect[i]) / ray.Direction[i]; deltaT[i] = -_width[i] / ray.Direction[i]; step[i] = -1; _out[i] = -1; } } for (;;) { var voxel = _voxels[Offset(pos[0], pos[1], pos[2])]; if (voxel != null) { if (voxel.Intersect(ray)) { return(true); } } var bits = (((nextCrossingT[0] < nextCrossingT[1]) ? 1 : 0) << 2) + (((nextCrossingT[0] < nextCrossingT[2]) ? 1 : 0) << 1) + (((nextCrossingT[1] < nextCrossingT[2]) ? 1 : 0)); var stepAxis = _cmpToAxis[bits]; if (ray.End < nextCrossingT[stepAxis]) { break; } pos[stepAxis] += step[stepAxis]; if (pos[stepAxis] == _out[stepAxis]) { break; } nextCrossingT[stepAxis] += deltaT[stepAxis]; } return(false); }