Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
        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;
		}