public override Intersection Intersect(Ray ray) { //closest hit Intersection closestIntersection = new Intersection(true); foreach (Sphere sphere in _spheres) { Intersection intersection = sphere.Intersect(ray); if ((!intersection.IsNull()) && intersection.GetTFirstHit() < closestIntersection.GetTFirstHit()) { closestIntersection = intersection; } } return(closestIntersection); }
//Raytrace all spheres (for bug testing) public Intersection getClosestIntersectionByCheckingAllEntities(Ray ray, float distance) { //nearest hit Intersection closestIntersection = new Intersection(true); foreach (Entity entityInPosition in _grid.GetEntityCollection()) { Intersection intersection = ((Sphere)entityInPosition).Intersect(ray); if ((!intersection.IsNull()) && (intersection.GetTFirstHit() > 0) && intersection.GetTFirstHit() < closestIntersection.GetTFirstHit()) { closestIntersection = intersection; } } return(closestIntersection); }
private Intersection getClosestIntersectionUsingVoxelTraverse(Ray ray, int distance) { //nearest hit Intersection closestIntersection = new Intersection(true); //TODO: Speed up by making a structure of the empty grids? Vector3 uPosition = ray.GetStart(); Vector3 vDirection = ray.GetDirection(); float scaledX = uPosition.X + 0.5f; float scaledY = uPosition.Y + 0.5f; float scaledZ = uPosition.Z + 0.5f; int voxelX = (int)Math.Floor(scaledX); int voxelY = (int)Math.Floor(scaledY); int voxelZ = (int)Math.Floor(scaledZ); int stepX = Math.Sign(vDirection.X); int stepY = Math.Sign(vDirection.Y); int stepZ = Math.Sign(vDirection.Z); int cellBoundaryX = voxelX + (stepX > 0 ? 1 : 0); int cellBoundaryY = voxelY + (stepY > 0 ? 1 : 0); int cellBoundaryZ = voxelZ + (stepZ > 0 ? 1 : 0); float tMaxX = (cellBoundaryX - scaledX) / vDirection.X; float tMaxY = (cellBoundaryY - scaledY) / vDirection.Y; float tMaxZ = (cellBoundaryZ - scaledZ) / vDirection.Z; if (Single.IsNaN(tMaxX) || Single.IsNegativeInfinity(tMaxX)) { tMaxX = Single.PositiveInfinity; } if (Single.IsNaN(tMaxY) || Single.IsNegativeInfinity(tMaxY)) { tMaxY = Single.PositiveInfinity; } if (Single.IsNaN(tMaxZ) || Single.IsNegativeInfinity(tMaxZ)) { tMaxZ = Single.PositiveInfinity; } float tDeltaX = stepX / vDirection.X; float tDeltaY = stepY / vDirection.Y; float tDeltaZ = stepZ / vDirection.Z; if (Single.IsNaN(tDeltaX) || Single.IsNegativeInfinity(tDeltaX)) { tDeltaX = Single.PositiveInfinity; } if (Single.IsNaN(tDeltaY) || Single.IsNegativeInfinity(tDeltaY)) { tDeltaY = Single.PositiveInfinity; } if (Single.IsNaN(tDeltaZ) || Single.IsNegativeInfinity(tDeltaZ)) { tDeltaZ = Single.PositiveInfinity; } int step = 0; do { Entity entityInPosition = _grid.GetEntityByVoxelPosition(voxelX, voxelY, voxelZ); if (entityInPosition != null) { Intersection intersection = entityInPosition.Intersect(ray); if ((!intersection.IsNull()) && (intersection.GetTFirstHit() > 0) && intersection.GetTFirstHit() < closestIntersection.GetTFirstHit()) { closestIntersection = intersection; break; } } if (tMaxX < tMaxY && tMaxX < tMaxZ) { voxelX += stepX; tMaxX += tDeltaX; } else if (tMaxY < tMaxZ) { voxelY += stepY; tMaxY += tDeltaY; } else { voxelZ += stepZ; tMaxZ += tDeltaZ; } step++; } while (step < distance); return(closestIntersection); }