//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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        protected Intersection getClosestIntersectionFromAntiSpheres(Intersection sphereIntersection, Ray ray)
        {
            bool insideSphere = sphereIntersection.GetTFirstHit() == sphereIntersection.GetTFar();

            AntiIntersection[] antiSphereIntersectionList;
            bool antiSphereIntersectionListIsHit;

            calculateAntiSphereIntersections(ray, out antiSphereIntersectionList, out antiSphereIntersectionListIsHit);
            if (antiSphereIntersectionListIsHit)
            {
                AntiIntersection farthestAntiIntersection = getFarthestAntiIntersection(sphereIntersection.GetTNear(), sphereIntersection.GetTFar(), antiSphereIntersectionList);
                if (farthestAntiIntersection.IsHit())
                {
                    var intersection = this.Intersect(farthestAntiIntersection.GetPositionFar(), farthestAntiIntersection.GetNormalFarTexture());
                    sphereIntersection = farthestAntiIntersection.CreateIntersection(intersection.GetNormalFirstHitTexture());
                }
                else if (farthestAntiIntersection.IsInfinite())
                {
                    sphereIntersection = new Intersection(true);
                }
            }
            return(sphereIntersection);
        }
        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);
        }