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 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); }
public IEnumerable IntersectionIterator(Ray ray) { if (ray.Intersection(Aabb)) { IPrimitive checkFirst = nodeA; IPrimitive checkSecond = nodeB; if (ray.directionNormal[splitingPlane] < 0) { checkFirst = nodeB; checkSecond = nodeA; } foreach (IntersectInfo info in checkFirst.IntersectionIterator(ray)) { if (info != null && info.hitType != IntersectionType.None) { yield return info; } } if (checkSecond != null) { foreach (IntersectInfo info in checkSecond.IntersectionIterator(ray)) { if (info != null && info.hitType != IntersectionType.None) { yield return info; } } } } }
public IntersectInfo GetClosestIntersection(Ray ray) { if (ray.Intersection(Aabb)) { IPrimitive checkFirst = nodeA; IPrimitive checkSecond = nodeB; if (ray.directionNormal[splitingPlane] < 0) { checkFirst = nodeB; checkSecond = nodeA; } IntersectInfo infoFirst = checkFirst.GetClosestIntersection(ray); if (infoFirst != null && infoFirst.hitType != IntersectionType.None) { if (ray.isShadowRay) { return infoFirst; } else { ray.maxDistanceToConsider = infoFirst.distanceToHit; } } if (checkSecond != null) { IntersectInfo infoSecond = checkSecond.GetClosestIntersection(ray); if (infoSecond != null && infoSecond.hitType != IntersectionType.None) { if (ray.isShadowRay) { return infoSecond; } else { ray.maxDistanceToConsider = infoSecond.distanceToHit; } } if (infoFirst != null && infoFirst.hitType != IntersectionType.None && infoFirst.distanceToHit >= 0) { if (infoSecond != null && infoSecond.hitType != IntersectionType.None && infoSecond.distanceToHit < infoFirst.distanceToHit && infoSecond.distanceToHit >= 0) { return infoSecond; } else { return infoFirst; } } return infoSecond; // we don't have to test it because it didn't hit. } return infoFirst; } return null; }