Exemple #1
0
        public void PolygonHitTests()
        {
            SolidMaterial redStuff = new SolidMaterial(new ColorF(1, 0, 0), 0, 0, 2);
            {
                TriangleShape facingPositiveX = new TriangleShape(new Vector3(0, 1, -1), new Vector3(0, 0, 1), new Vector3(0, -1, -1), redStuff);
                IntersectInfo positiveXInfo   = facingPositiveX.GetClosestIntersection(new Ray(new Vector3(1, 0, 0), new Vector3(-1, 0, 0)));
                Assert.IsTrue(positiveXInfo.HitPosition == new Vector3(0, 0, 0));
                Assert.IsTrue(positiveXInfo.HitType == IntersectionType.FrontFace);
                Assert.IsTrue(positiveXInfo.ClosestHitObject == facingPositiveX);
                Assert.IsTrue(positiveXInfo.DistanceToHit == 1);

                IntersectInfo negativeXInfo = facingPositiveX.GetClosestIntersection(new Ray(new Vector3(-1, 0, 0), new Vector3(1, 0, 0)));
                Assert.IsTrue(negativeXInfo == null);
            }
            {
                TriangleShape facingNegativeX = new TriangleShape(new Vector3(0, -1, -1), new Vector3(0, 0, 1), new Vector3(0, 1, -1), redStuff);
                IntersectInfo positiveXInfo   = facingNegativeX.GetClosestIntersection(new Ray(new Vector3(1, 0, 0), new Vector3(-1, 0, 0)));
                Assert.IsTrue(positiveXInfo == null);

                IntersectInfo negativeXInfo = facingNegativeX.GetClosestIntersection(new Ray(new Vector3(-1, 0, 0), new Vector3(1, 0, 0)));
                Assert.IsTrue(negativeXInfo.HitPosition == new Vector3(0, 0, 0));
                Assert.IsTrue(negativeXInfo.HitType == IntersectionType.FrontFace);
                Assert.IsTrue(negativeXInfo.ClosestHitObject == facingNegativeX);
                Assert.IsTrue(negativeXInfo.DistanceToHit == 1);
            }
        }
Exemple #2
0
        public override (double u, double v) GetUv(IntersectInfo info)
        {
            Vector3 vn = new Vector3(0, 1, 0).GetNormal();             // north pole / up
            Vector3 ve = new Vector3(0, 0, 1).GetNormal();             // equator / sphere orientation
            Vector3 vp = (info.HitPosition - position).GetNormal();    //points from center of sphere to intersection

            double phi = Math.Acos(-Vector3Ex.Dot(vp, vn));
            double v   = (phi * 2 / Math.PI) - 1;

            double sinphi = Vector3Ex.Dot(ve, vp) / Math.Sin(phi);

            sinphi = sinphi < -1 ? -1 : sinphi > 1 ? 1 : sinphi;
            double theta = Math.Acos(sinphi) * 2 / Math.PI;

            double u;

            if (Vector3Ex.Dot(Vector3Ex.Cross(vn, ve), vp) > 0)
            {
                u = theta;
            }
            else
            {
                u = 1 - theta;
            }

            return(u, v);
        }
Exemple #3
0
        public override IEnumerable IntersectionIterator(Ray ray)
        {
            double minDistFound;
            double maxDistFound;
            int    minAxis;
            int    maxAxis;

            if (intersect(ray, out minDistFound, out maxDistFound, out minAxis, out maxAxis))
            {
                if ((ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace)
                {
                    IntersectInfo info = new IntersectInfo();
                    info.hitType              = IntersectionType.FrontFace;
                    info.closestHitObject     = this;
                    info.hitPosition          = ray.origin + ray.directionNormal * minDistFound;
                    info.normalAtHit[minAxis] = ray.sign[minAxis] == Ray.Sign.negative ? 1 : -1; // you hit the side that is oposite your sign
                    info.distanceToHit        = minDistFound;
                    yield return(info);
                }

                if ((ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace)
                {
                    IntersectInfo info = new IntersectInfo();
                    info.hitType              = IntersectionType.BackFace;
                    info.closestHitObject     = this;
                    info.hitPosition          = ray.origin + ray.directionNormal * maxDistFound;
                    info.normalAtHit[maxAxis] = ray.sign[maxAxis] == Ray.Sign.negative ? 1 : -1;
                    info.distanceToHit        = maxDistFound;
                    yield return(info);
                }
            }
        }
        public static void ReadInList(List <IntersectInfo> listToPopulate, StreamReader reader)
        {
            int count;

            int.TryParse(reader.ReadLine(), NumberStyles.Number, null, out count);
            for (int i = 0; i < count; i++)
            {
                IntersectInfo info    = new IntersectInfo();
                string        line    = reader.ReadLine();
                string[]      strings = line.Split(',');
                if (strings[0] == IntersectionType.FrontFace.ToString())
                {
                    info.HitType = IntersectionType.FrontFace;
                }
                else
                {
                    if (strings[0] != IntersectionType.BackFace.ToString())
                    {
                        throw new Exception("Has to be back or front.");
                    }

                    info.HitType = IntersectionType.BackFace;
                }

                double.TryParse(strings[1], NumberStyles.Number, null, out info.DistanceToHit);
                listToPopulate.Add(info);
            }
        }
        public IntersectInfo GetClosestIntersection(Ray ray)
        {
            if (ray.Intersection(Aabb))
            {
                IPrimitive checkFirst  = nodeA;
                IPrimitive checkSecond = nodeB;
                if (ray.directionNormal[splittingPlane] < 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);
        }
 public IntersectInfo(IntersectInfo copyInfo)
 {
     this.hitType          = copyInfo.hitType;
     this.closestHitObject = copyInfo.closestHitObject;
     this.hitPosition      = copyInfo.hitPosition;
     this.normalAtHit      = copyInfo.normalAtHit;
     this.distanceToHit    = copyInfo.distanceToHit;
 }
 public IntersectInfo(IntersectInfo copyInfo)
 {
     this.HitType          = copyInfo.HitType;
     this.ClosestHitObject = copyInfo.ClosestHitObject;
     this.HitPosition      = copyInfo.HitPosition;
     this.NormalAtHit      = copyInfo.NormalAtHit;
     this.DistanceToHit    = copyInfo.DistanceToHit;
 }
Exemple #8
0
        public ColorF FullyTraceRay(Ray ray, Scene scene, out IntersectInfo primaryInfo)
        {
            primaryInfo = TracePrimaryRay(ray, scene);
            if (primaryInfo.HitType != IntersectionType.None)
            {
                ColorF totalColor = CreateAndTraceSecondaryRays(primaryInfo, ray, scene, 0);
                return(totalColor);
            }

            return(scene.background.Color);
        }
Exemple #9
0
        public override (double u, double v) GetUv(IntersectInfo info)
        {
            Vector3Float normal = Plane.Normal;
            Vector3Float vecU   = new Vector3Float(normal.Y, normal.Z, -normal.X);
            Vector3Float vecV   = vecU.Cross(Plane.Normal);

            var u = new Vector3Float(info.HitPosition).Dot(vecU);
            var v = new Vector3Float(info.HitPosition).Dot(vecV);

            return(u, v);
        }
Exemple #10
0
        public override (double u, double v) GetUv(IntersectInfo info)
        {
            Vector3 Position = plane.Normal;
            Vector3 vecU     = new Vector3(Position.Y, Position.Z, -Position.X);
            Vector3 vecV     = Vector3Ex.Cross(vecU, plane.Normal);

            double u = Vector3Ex.Dot(info.HitPosition, vecU);
            double v = Vector3Ex.Dot(info.HitPosition, vecV);

            return(u, v);
        }
        public override (double u, double v) GetUv(IntersectInfo info)
        {
            Vector3Float normal = Plane.Normal;
            Vector3Float vecU   = new Vector3Float(normal.y, normal.z, -normal.x);
            Vector3Float vecV   = Vector3Float.Cross(vecU, Plane.Normal);

            var u = Vector3Float.Dot(new Vector3Float(info.HitPosition), vecU);
            var v = Vector3Float.Dot(new Vector3Float(info.HitPosition), vecV);

            return(u, v);
        }
 public ColorF GetColor(IntersectInfo info)
 {
     if (Material.HasTexture)
     {
         var uv = GetUv(info);
         return(Material.GetColor(uv.u, uv.v));
     }
     else
     {
         return(Material.GetColor(0, 0));
     }
 }
Exemple #13
0
 public override RGBA_Floats GetColor(IntersectInfo info)
 {
     if (Material.HasTexture)
     {
         throw new NotImplementedException();
     }
     else
     {
         // skip uv calculation, just get the color
         return(this.Material.GetColor(0, 0));
     }
 }
Exemple #14
0
        /// <summary>
        /// This implementation of intersect uses the fastest ray-sphere intersection algorithm I could find
        /// on the internet.
        /// </summary>
        /// <param name="ray"></param>
        /// <returns></returns>
        public override IntersectInfo GetClosestIntersection(Ray ray)
        {
            double radiusSquared = radius * radius;

            Vector3 deltaFromShpereCenterToRayOrigin             = ray.origin - this.position;
            double  distanceFromSphereCenterToRayOrigin          = Vector3Ex.Dot(deltaFromShpereCenterToRayOrigin, ray.directionNormal);   // negative means the sphere is in front of the ray.
            double  lengthFromRayOrginToSphereCenterSquared      = Vector3Ex.Dot(deltaFromShpereCenterToRayOrigin, deltaFromShpereCenterToRayOrigin);
            double  lengthFromRayOrigintoNearEdgeOfSphereSquared = lengthFromRayOrginToSphereCenterSquared - radiusSquared;
            double  distanceFromSphereCenterToRaySquared         = distanceFromSphereCenterToRayOrigin * distanceFromSphereCenterToRayOrigin;
            double  amountSphereCenterToRayIsGreaterThanRayOriginToEdgeSquared = distanceFromSphereCenterToRaySquared - lengthFromRayOrigintoNearEdgeOfSphereSquared;

            if (amountSphereCenterToRayIsGreaterThanRayOriginToEdgeSquared > 0 ||
                (ray.intersectionType == IntersectionType.BackFace && lengthFromRayOrginToSphereCenterSquared < radiusSquared))                    // yes, that's it, we found the intersection!
            {
                IntersectInfo info = new IntersectInfo();
                info.closestHitObject = this;
                info.hitType          = IntersectionType.FrontFace;
                if (ray.isShadowRay)
                {
                    return(info);
                }
                double distanceFromRayOriginToSphereCenter = -distanceFromSphereCenterToRayOrigin;

                double amountSphereCenterToRayIsGreaterThanRayOriginToEdge = Math.Sqrt(amountSphereCenterToRayIsGreaterThanRayOriginToEdgeSquared);
                if (ray.intersectionType == IntersectionType.FrontFace)
                {
                    double distanceToFrontHit = distanceFromRayOriginToSphereCenter - amountSphereCenterToRayIsGreaterThanRayOriginToEdge;
                    if (distanceToFrontHit > ray.maxDistanceToConsider || distanceToFrontHit < ray.minDistanceToConsider)
                    {
                        return(null);
                    }
                    info.distanceToHit = distanceToFrontHit;
                    info.HitPosition   = ray.origin + ray.directionNormal * info.distanceToHit;
                    info.normalAtHit   = (info.HitPosition - position).GetNormal();
                }
                else                 // check back faces
                {
                    double distanceToBackHit = distanceFromRayOriginToSphereCenter + amountSphereCenterToRayIsGreaterThanRayOriginToEdge;
                    if (distanceToBackHit > ray.maxDistanceToConsider || distanceToBackHit < ray.minDistanceToConsider)
                    {
                        return(null);
                    }
                    info.hitType       = IntersectionType.BackFace;
                    info.distanceToHit = distanceToBackHit;
                    info.HitPosition   = ray.origin + ray.directionNormal * info.distanceToHit;
                    info.normalAtHit   = -(info.HitPosition - position).GetNormal();
                }

                return(info);
            }

            return(null);
        }
Exemple #15
0
        private static void TestSingleAngle(Scene scene, RayTracer raytracer, double advance, int i)
        {
            var sampleXY = new Vector2(48, 0);

            sampleXY.Rotate(advance * i);
            Vector3 rayOrigin = new Vector3(sampleXY, 10);

            Ray           ray         = new Ray(rayOrigin, -Vector3.UnitZ);
            IntersectInfo primaryInfo = raytracer.TracePrimaryRay(ray, scene);

            Assert.IsTrue(primaryInfo.HitType == IntersectionType.FrontFace, "always have a hit");
        }
Exemple #16
0
        public IntersectInfo TracePrimaryRay(Ray ray, Scene scene)
        {
            IntersectInfo primaryRayIntersection = new IntersectInfo();

            foreach (IPrimitive shapeToTest in scene.shapes)
            {
                IntersectInfo info = shapeToTest.GetClosestIntersection(ray);
                if (info != null && info.hitType != IntersectionType.None && info.distanceToHit < primaryRayIntersection.distanceToHit && info.distanceToHit >= 0)
                {
                    primaryRayIntersection = info;
                }
            }
            return(primaryRayIntersection);
        }
Exemple #17
0
        public override RGBA_Floats GetColor(IntersectInfo info)
        {
            if (Material.HasTexture)
            {
                Vector3 Position = plane.planeNormal;
                Vector3 vecU     = new Vector3(Position.y, Position.z, -Position.x);
                Vector3 vecV     = Vector3.Cross(vecU, plane.planeNormal);

                double u = Vector3.Dot(info.hitPosition, vecU);
                double v = Vector3.Dot(info.hitPosition, vecV);
                return(Material.GetColor(u, v));
            }
            else
            {
                return(Material.GetColor(0, 0));
            }
        }
        private static bool GetRemoveRegion(List <IntersectInfo> subtractList, int startIndex, out int regionStartIndex, out int regionEndIndex)
        {
            regionStartIndex = startIndex;
            regionEndIndex   = startIndex;
            double insideCount   = 0;
            int    subtractCount = subtractList.Count;

            for (int subtractIndex = startIndex; subtractIndex < subtractCount; subtractIndex++)
            {
                IntersectInfo subtractInfo = subtractList[subtractIndex];
                if (subtractInfo.HitType == IntersectionType.FrontFace)
                {
                    if (insideCount == 0)
                    {
                        regionStartIndex = subtractIndex;
                    }
                    insideCount++;
                }
                else if (subtractInfo.HitType == IntersectionType.BackFace)
                {
                    if (insideCount == 0)
                    {
                        throw new Exception("You should not have a back face without a matching front face.");
                    }
                    insideCount--;
                    if (insideCount == 0)
                    {
                        // let's check that there is not another entry aligned exactly with this exit
                        int nextIndex = subtractIndex + 1;
                        if (nextIndex >= subtractCount || subtractList[subtractIndex].DistanceToHit + Ray.sameSurfaceOffset < subtractList[nextIndex].DistanceToHit)
                        {
                            // we have our subtract region
                            regionEndIndex = subtractIndex;
                            return(true);
                        }
                    }
                }
                else
                {
                    throw new Exception("There should be no 'none's in the hit types.");
                }
            }

            return(false);
        }
Exemple #19
0
        public override IEnumerable IntersectionIterator(Ray ray)
        {
            double radiusSquared = radius * radius;

            Vector3 deltaFromShpereCenterToRayOrigin             = ray.origin - this.position;
            double  distanceFromSphereCenterToRayOrigin          = Vector3Ex.Dot(deltaFromShpereCenterToRayOrigin, ray.directionNormal);   // negative means the sphere is in front of the ray.
            double  lengthFromRayOrginToSphereCenterSquared      = Vector3Ex.Dot(deltaFromShpereCenterToRayOrigin, deltaFromShpereCenterToRayOrigin);
            double  lengthFromRayOrigintoNearEdgeOfSphereSquared = lengthFromRayOrginToSphereCenterSquared - radiusSquared;
            double  distanceFromSphereCenterToRaySquared         = distanceFromSphereCenterToRayOrigin * distanceFromSphereCenterToRayOrigin;
            double  amountSphereCenterToRayIsGreaterThanRayOriginToEdgeSquared = distanceFromSphereCenterToRaySquared - lengthFromRayOrigintoNearEdgeOfSphereSquared;

            if (amountSphereCenterToRayIsGreaterThanRayOriginToEdgeSquared > 0)
            {
                double distanceFromRayOriginToSphereCenter = -distanceFromSphereCenterToRayOrigin;
                double amountSphereCenterToRayIsGreaterThanRayOriginToEdge = Math.Sqrt(amountSphereCenterToRayIsGreaterThanRayOriginToEdgeSquared);

                if ((ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace)
                {
                    IntersectInfo info = new IntersectInfo();
                    info.hitType          = IntersectionType.FrontFace;
                    info.closestHitObject = this;
                    double distanceToFrontHit = distanceFromRayOriginToSphereCenter - amountSphereCenterToRayIsGreaterThanRayOriginToEdge;

                    info.distanceToHit = distanceToFrontHit;
                    info.HitPosition   = ray.origin + ray.directionNormal * info.distanceToHit;
                    info.normalAtHit   = (info.HitPosition - position).GetNormal();

                    yield return(info);
                }

                if ((ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace)
                {
                    IntersectInfo info = new IntersectInfo();
                    info.hitType          = IntersectionType.BackFace;
                    info.closestHitObject = this;
                    double distanceToBackHit = distanceFromRayOriginToSphereCenter + amountSphereCenterToRayIsGreaterThanRayOriginToEdge;

                    info.distanceToHit = distanceToBackHit;
                    info.HitPosition   = ray.origin + ray.directionNormal * info.distanceToHit;
                    info.normalAtHit   = -(info.HitPosition - position).GetNormal();

                    yield return(info);
                }
            }
        }
Exemple #20
0
        public override IntersectInfo GetClosestIntersection(Ray ray)
        {
            IntersectInfo info = new IntersectInfo();

            double minDistFound;
            double maxDistFound;
            int    minAxis;
            int    maxAxis;

            if (intersect(ray, out minDistFound, out maxDistFound, out minAxis, out maxAxis))
            {
                if (ray.intersectionType == IntersectionType.FrontFace)
                {
                    if (minDistFound > ray.minDistanceToConsider && minDistFound < ray.maxDistanceToConsider)
                    {
                        info.hitType = IntersectionType.FrontFace;
                        if (ray.isShadowRay)
                        {
                            return(info);
                        }
                        info.closestHitObject     = this;
                        info.hitPosition          = ray.origin + ray.directionNormal * minDistFound;
                        info.normalAtHit[minAxis] = ray.sign[minAxis] == Ray.Sign.negative ? 1 : -1; // you hit the side that is oposite your sign
                        info.distanceToHit        = minDistFound;
                    }
                }
                else // check back faces
                {
                    if (maxDistFound > ray.minDistanceToConsider && maxDistFound < ray.maxDistanceToConsider)
                    {
                        info.hitType = IntersectionType.BackFace;
                        if (ray.isShadowRay)
                        {
                            return(info);
                        }
                        info.closestHitObject     = this;
                        info.hitPosition          = ray.origin + ray.directionNormal * maxDistFound;
                        info.normalAtHit[maxAxis] = ray.sign[maxAxis] == Ray.Sign.negative ? 1 : -1;
                        info.distanceToHit        = maxDistFound;
                    }
                }
            }

            return(info);
        }
        public IntersectInfo GetClosestIntersection(Ray ray)
        {
            IntersectInfo bestInfo = null;

            foreach (IPrimitive item in Items)
            {
                IntersectInfo info = item.GetClosestIntersection(ray);
                if (info != null && info.hitType != IntersectionType.None && info.distanceToHit >= 0)
                {
                    if (bestInfo == null || info.distanceToHit < bestInfo.distanceToHit)
                    {
                        bestInfo = info;
                    }
                }
            }

            return(bestInfo);
        }
Exemple #22
0
        public override IntersectInfo GetClosestIntersection(Ray ray)
        {
            bool   inFront;
            double distanceToHit = plane.GetDistanceToIntersection(ray, out inFront);

            if (distanceToHit > 0)
            {
                IntersectInfo info = new IntersectInfo();
                info.closestHitObject = this;
                info.hitType          = IntersectionType.FrontFace;
                info.hitPosition      = ray.origin + ray.directionNormal * distanceToHit;
                info.normalAtHit      = plane.planeNormal;
                info.distanceToHit    = distanceToHit;

                return(info);
            }

            return(null);
        }
        public override void OnMouseDown(MouseEventArgs mouseEvent)
        {
            base.OnMouseDown(mouseEvent);

            lastMouseMovePoint.x = mouseEvent.X;
            lastMouseMovePoint.y = mouseEvent.Y;

            if (Focused && MouseCaptured)
            {
                if (trackBallController.CurrentTrackingType == TrackBallController.MouseDownType.None)
                {
                    if (Focused && MouseCaptured && mouseEvent.Button == MouseButtons.Left)
                    {
                        trackBallController.OnMouseDown(lastMouseMovePoint, Matrix4X4.Identity);
                    }
                    else if (mouseEvent.Button == MouseButtons.Middle)
                    {
                        trackBallController.OnMouseDown(lastMouseMovePoint, Matrix4X4.Identity, TrackBallController.MouseDownType.Translation);
                    }
                }

                if (MouseCaptured)
                {
                    lastMouseMovePoint.x             = mouseEvent.X;
                    lastMouseMovePoint.y             = mouseEvent.Y;
                    cameraDataAtStartOfMouseTracking = cameraData;
                    cameraDataAtStartOfMouseTracking.cameraMatrix = scene.camera.axisToWorld;

                    Ray rayAtPoint = scene.camera.GetRay(lastMouseMovePoint.x, lastMouseMovePoint.y);

                    IntersectInfo info = raytracer.TracePrimaryRay(rayAtPoint, scene);
                    if (info != null)
                    {
                        focusedObject = (BaseShape)info.closestHitObject;
                        if (focusedObject != null && mouseEvent.Clicks == 2)
                        {
                            cameraData.lookAtPoint = focusedObject.GetAxisAlignedBoundingBox().Center;
                            OrientCamera();
                        }
                    }
                }
            }
        }
Exemple #24
0
        public override IntersectInfo GetClosestIntersection(Ray ray)
        {
            bool  inFront;
            float distanceToHit;

            if (plane.RayHitPlane(ray, out distanceToHit, out inFront))
            {
                bool wantFrontAndInFront = (ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace && inFront;
                bool wantBackAndInBack   = (ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace && !inFront;
                if (wantFrontAndInFront || wantBackAndInBack)
                {
                    Vector3 hitPosition = ray.origin + ray.directionNormal * distanceToHit;

                    bool haveHitIn2D = false;
                    if (majorAxis == 0)
                    {
                        haveHitIn2D = Check2DHitOnMajorAxis(hitPosition.y, hitPosition.z);
                    }
                    else if (majorAxis == 1)
                    {
                        haveHitIn2D = Check2DHitOnMajorAxis(hitPosition.x, hitPosition.z);
                    }
                    else
                    {
                        haveHitIn2D = Check2DHitOnMajorAxis(hitPosition.x, hitPosition.y);
                    }
                    if (haveHitIn2D)
                    {
                        IntersectInfo info = new IntersectInfo();
                        info.closestHitObject = this;
                        info.hitType          = IntersectionType.FrontFace;
                        info.hitPosition      = hitPosition;
                        info.normalAtHit      = new Vector3(plane.planeNormal);
                        info.distanceToHit    = distanceToHit;

                        return(info);
                    }
                }
            }

            return(null);
        }
Exemple #25
0
        public override RGBA_Floats GetColor(IntersectInfo info)
        {
            if (Material.HasTexture)
            {
                throw new NotImplementedException();
#if false
                //Vector vecU = new Vector(hit.y - Position.y, hit.z - Position.z, Position.x-hit.x);
                Vector3 Position = Transform.Position;
                Vector3 vecU     = new Vector3D((P1.y + P2.y) / 2 - Position.y, (P1.z + P2.z) / 2 - Position.z, Position.x - (P1.x + P2.x) / 2).GetNormal();
                Vector3 vecV     = vecU.Cross((P1 + P2) / 2 - Position).GetNormal();

                double u = Vector3.Dot(info.hitPosition, vecU);
                double v = Vector3.Dot(info.hitPosition, vecV);
                return(Material.GetColor(u, v));
#endif
            }
            else
            {
                return(Material.GetColor(0, 0));
            }
        }
Exemple #26
0
 public void FullyTraceRayBundle(RayBundle rayBundle, IntersectInfo[] intersectionsForBundle, Scene scene)
 {
     TracePrimaryRayBundle(rayBundle, intersectionsForBundle, scene);
     for (int i = 0; i < rayBundle.rayArray.Length; i++)
     {
         try
         {
             IntersectInfo primaryInfo = TracePrimaryRay(rayBundle.rayArray[i], scene);
             if (intersectionsForBundle[i].HitType != IntersectionType.None)
             {
                 intersectionsForBundle[i].TotalColor = CreateAndTraceSecondaryRays(primaryInfo, rayBundle.rayArray[i], scene, 0);
             }
             else
             {
                 intersectionsForBundle[i].TotalColor = scene.background.Color;
             }
         }
         catch
         {
         }
     }
 }
        private static bool IsInside(List <IntersectInfo> listToCheck, double distance)
        {
            int insideCount = 0;
            int conut       = listToCheck.Count;

            for (int index = 0; index < conut; index++)
            {
                IntersectInfo info = listToCheck[index];
                if (info.hitType == HitType.FrontFace)
                {
                    if (insideCount == 0)
                    {
                        startSubtract = info.distanceToHit;
                        // add all the elements from the last end to the new start
                    }
                    insideCount++;
                }
                else if (info.hitType == HitType.BackFace)
                {
                    insideCount--;
                    if (insideCount == 0)
                    {
                        if (IsInside(allPrimary, info.distanceToHit))
                        {
                            result.Add(info);
                        }
                        lastSubtractEnd = info.distanceToHit;
                        // add all the front face points between lastSubtractEnd and startSubtract
                    }
                }
                else
                {
                    throw new Exception("There should be no 'none's in the hit types.");
                }
            }

            return(false);
        }
Exemple #28
0
        public void DiscoveredBadIntersectInfoListSubtraction()
        {
            string primaryString  = @"2
FrontFace, 6.55505298172777
BackFace, 7.05554361306285";
            string subtractString = @"4
FrontFace, 7.05554387355765
BackFace, 7.14478176419901
FrontFace, 7.28926063619785
BackFace, 7.36209329430552";

            List <IntersectInfo> allPrimary = new List <IntersectInfo>();

            IntersectInfo.ReadInList(allPrimary, new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(primaryString))));

            List <IntersectInfo> allSubtract = new List <IntersectInfo>();

            IntersectInfo.ReadInList(allSubtract, new StreamReader(new MemoryStream(Encoding.ASCII.GetBytes(subtractString))));

            List <IntersectInfo> result = new List <IntersectInfo>();

            IntersectInfo.Subtract(allPrimary, allSubtract, result);
        }
        public override RGBA_Floats GetColor(IntersectInfo info)
        {
            if (Material.HasTexture)
            {
                Vector3 vn = new Vector3(0, 1, 0).GetNormal();                 // north pole / up
                Vector3 ve = new Vector3(0, 0, 1).GetNormal();                 // equator / sphere orientation
                Vector3 vp = (info.hitPosition - position).GetNormal();        //points from center of sphere to intersection

                double phi = Math.Acos(-Vector3.Dot(vp, vn));
                double v   = (phi * 2 / Math.PI) - 1;

                double sinphi = Vector3.Dot(ve, vp) / Math.Sin(phi);
                sinphi = sinphi < -1 ? -1 : sinphi > 1 ? 1 : sinphi;
                double theta = Math.Acos(sinphi) * 2 / Math.PI;

                double u;

                if (Vector3.Dot(Vector3.Cross(vn, ve), vp) > 0)
                {
                    u = theta;
                }
                else
                {
                    u = 1 - theta;
                }

                // alternative but worse implementation
                //double u = Math.Atan2(vp.x, vp.z);
                //double v = Math.Acos(vp.y);
                return(this.Material.GetColor(u, v));
            }
            else
            {
                // skip uv calculation, just get the color
                return(this.Material.GetColor(0, 0));
            }
        }
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            if (trackBallController.CurrentTrackingType != TrackBallController.MouseDownType.None)
            {
                lastMouseMovePoint.x = mouseEvent.X;
                lastMouseMovePoint.y = mouseEvent.Y;
                trackBallController.OnMouseMove(lastMouseMovePoint);
                NeedRedraw = true;
                Invalidate();
            }

            if (Focused && MouseCaptured)
            {
                lastMouseMovePoint.x = mouseEvent.X;
                lastMouseMovePoint.y = mouseEvent.Y;

                cameraData = cameraDataAtStartOfMouseTracking;
                //cameraData.Rotate(trackBallRotation);

                //OrientCamera();
            }

            lastMouseMovePoint.x = mouseEvent.X;
            lastMouseMovePoint.y = mouseEvent.Y;

            Ray rayAtPoint = scene.camera.GetRay(lastMouseMovePoint.x, lastMouseMovePoint.y);

            IntersectInfo primaryInfo = raytracer.TracePrimaryRay(rayAtPoint, scene);

            if (primaryInfo.hitType != IntersectionType.None)
            {
                mouseOverColor = raytracer.CreateAndTraceSecondaryRays(primaryInfo, rayAtPoint, scene, 0);
            }
        }