public void AlongRay(Ray ray, List <T> results) { if (ray.Intersection(Aabb)) { // check all the items that are part of this object foreach (var item in Items) { if (item is IIntersectable intersectable) { RayHitInfo info = intersectable.GetIntersection(ray); if (info != null && info.HitType != IntersectionType.None && info.DistanceToHit >= 0) { results.Add(item.Item); } } else if (ray.Intersection(item.Aabb)) { results.Add(item.Item); } } nodeA?.AlongRay(ray, results); nodeB?.AlongRay(ray, results); } }
public RayHitInfo(RayHitInfo copyInfo) { this.HitType = copyInfo.HitType; this.ClosestHitObject = copyInfo.ClosestHitObject; this.HitPosition = copyInfo.HitPosition; this.NormalAtHit = copyInfo.NormalAtHit; this.DistanceToHit = copyInfo.DistanceToHit; }
public RayHitInfo GetClosestIntersection(AxisAlignedBoundingBox bounds) { RayHitInfo info = new RayHitInfo(); double minDistFound; double maxDistFound; int minAxis; int maxAxis; if (Intersect(bounds, out minDistFound, out maxDistFound, out minAxis, out maxAxis)) { if (this.intersectionType == IntersectionType.FrontFace) { if (minDistFound > this.minDistanceToConsider && minDistFound < this.maxDistanceToConsider) { info.HitType = IntersectionType.FrontFace; if (this.isShadowRay) { return(info); } info.ClosestHitObject = bounds; info.HitPosition = this.origin + this.directionNormal * minDistFound; Vector3 normalAtHit = default(Vector3); normalAtHit[minAxis] = this.sign[minAxis] == Ray.Sign.negative ? 1 : -1; // you hit the side that is opposite your sign info.NormalAtHit = normalAtHit; info.DistanceToHit = minDistFound; } } else // check back faces { if (maxDistFound > this.minDistanceToConsider && maxDistFound < this.maxDistanceToConsider) { info.HitType = IntersectionType.BackFace; if (this.isShadowRay) { return(info); } info.ClosestHitObject = bounds; info.HitPosition = this.origin + this.directionNormal * maxDistFound; Vector3 normalAtHit = default(Vector3); normalAtHit[minAxis] = this.sign[minAxis] == Ray.Sign.negative ? 1 : -1; // you hit the side that is opposite your sign info.NormalAtHit = normalAtHit; info.DistanceToHit = maxDistFound; } } } return(info); }
public RayHitInfo GetClosestIntersection(Ray ray) { RayHitInfo bestIntersect = null; if (ray.Intersection(Aabb)) { // check all the items that are part of this object foreach (var item in Items) { if (item is IIntersectable intersectable) { RayHitInfo info = intersectable.GetIntersection(ray); if (info != null && info.HitType != IntersectionType.None && info.DistanceToHit >= 0) { if (ray.isShadowRay) { return(info); } else if (bestIntersect == null || info.DistanceToHit < bestIntersect.DistanceToHit) { bestIntersect = info; ray.maxDistanceToConsider = bestIntersect.DistanceToHit; } } } // we will just be hitting the bounding box of the type else { RayHitInfo info = ray.GetClosestIntersection(item.Aabb); if (info != null && info.HitType != IntersectionType.None && info.DistanceToHit >= 0) { info.ClosestHitObject = item.Item; if (ray.isShadowRay) { return(info); } else if (bestIntersect == null || info.DistanceToHit < bestIntersect.DistanceToHit) { bestIntersect = info; ray.maxDistanceToConsider = bestIntersect.DistanceToHit; } } } } var checkFirst = nodeA; var checkSecond = nodeB; if (ray.directionNormal[splittingPlane] < 0) { checkFirst = nodeB; checkSecond = nodeA; } if (checkFirst != null) { RayHitInfo firstIntersect = checkFirst.GetClosestIntersection(ray); if (firstIntersect != null && firstIntersect.HitType != IntersectionType.None) { if (ray.isShadowRay) { return(firstIntersect); } else if (bestIntersect == null || firstIntersect.DistanceToHit < bestIntersect.DistanceToHit) { bestIntersect = firstIntersect; ray.maxDistanceToConsider = bestIntersect.DistanceToHit; } } } if (checkSecond != null) { RayHitInfo secondIntersect = checkSecond.GetClosestIntersection(ray); if (secondIntersect != null && secondIntersect.HitType != IntersectionType.None) { if (ray.isShadowRay) { return(secondIntersect); } else if (bestIntersect == null || secondIntersect.DistanceToHit < bestIntersect.DistanceToHit) { bestIntersect = secondIntersect; ray.maxDistanceToConsider = bestIntersect.DistanceToHit; } } } } return(bestIntersect); }