Beispiel #1
0
        public bool RayHitPlane(Ray ray, out double distanceToHit, out bool hitFrontOfPlane)
        {
            distanceToHit = double.PositiveInfinity;
            hitFrontOfPlane = false;

            double normalDotRayDirection = Vector3.Dot(planeNormal, ray.direction);
            if (normalDotRayDirection < TreatAsZero && normalDotRayDirection > -TreatAsZero) // the ray is parallel to the plane
            {
                return false;
            }

            if (normalDotRayDirection < 0)
            {
                hitFrontOfPlane = true;
            }

            double distanceToRayOriginFromOrigin = Vector3.Dot(planeNormal, ray.origin);

            double distanceToPlaneFromRayOrigin = distanceToPlaneFromOrigin - distanceToRayOriginFromOrigin;

            bool originInFrontOfPlane = distanceToPlaneFromRayOrigin < 0;

            bool originAndHitAreOnSameSide = originInFrontOfPlane == hitFrontOfPlane;
            if (!originAndHitAreOnSameSide)
            {
                return false;
            }

            distanceToHit = distanceToPlaneFromRayOrigin / normalDotRayDirection;
            return true;
        }
        public void SetPrintLevelingEquation(Vector3 position0, Vector3 position1, Vector3 position2, Vector2 bedCenter)
        {
            if (position0 == position1 || position1 == position2 || position2 == position0)
            {
                return;
            }

            Plane planeOfPoints = new Plane(position0, position1, position2);

            Ray ray = new Ray(new Vector3(bedCenter, 0), Vector3.UnitZ);
            bool inFront;
            double distanceToPlaneAtBedCenter = planeOfPoints.GetDistanceToIntersection(ray, out inFront);

            Matrix4X4 makePointsFlatMatrix = Matrix4X4.CreateTranslation(-bedCenter.x, -bedCenter.y, -distanceToPlaneAtBedCenter);
            makePointsFlatMatrix *= Matrix4X4.CreateRotation(planeOfPoints.planeNormal, Vector3.UnitZ);
            makePointsFlatMatrix *= Matrix4X4.CreateTranslation(bedCenter.x, bedCenter.y, 0);//distanceToPlaneAtBedCenter);

            bedLevelMatrix = Matrix4X4.Invert(makePointsFlatMatrix);

            {
                // test that the points come back as 0 zs
                Vector3 outPosition0 = Vector3.TransformPosition(position0, makePointsFlatMatrix);
                Vector3 outPosition1 = Vector3.TransformPosition(position1, makePointsFlatMatrix);
                Vector3 outPosition2 = Vector3.TransformPosition(position2, makePointsFlatMatrix);

                Vector3 printPosition0 = new Vector3(ActiveSliceSettings.Instance.GetPrintLevelSamplePosition(0), 0);
                Vector3 printPosition1 = new Vector3(ActiveSliceSettings.Instance.GetPrintLevelSamplePosition(1), 0);
                Vector3 printPosition2 = new Vector3(ActiveSliceSettings.Instance.GetPrintLevelSamplePosition(2), 0);

                Vector3 leveledPositon0 = Vector3.TransformPosition(printPosition0, bedLevelMatrix);
                Vector3 leveledPositon1 = Vector3.TransformPosition(printPosition1, bedLevelMatrix);
                Vector3 leveledPositon2 = Vector3.TransformPosition(printPosition2, bedLevelMatrix);
            }
        }
Beispiel #3
0
        internal void PlaneGetDistanceToIntersection()
        {
            Plane testPlane = new Plane(Vector3.UnitZ, 10);
            bool hitFrontOfPlane;
            double distanceToHit;

            Ray lookingAtFrontOfPlane = new Ray(new Vector3(0, 0, 11), new Vector3(0, 0, -1));
            Assert.IsTrue(testPlane.RayHitPlane(lookingAtFrontOfPlane, out distanceToHit, out hitFrontOfPlane));
            Assert.IsTrue(distanceToHit == 1);
            Assert.IsTrue(hitFrontOfPlane);

            Ray notLookingAtFrontOfPlane = new Ray(new Vector3(0, 0, 11), new Vector3(0, 0, 1));
            Assert.IsTrue(!testPlane.RayHitPlane(notLookingAtFrontOfPlane, out distanceToHit, out hitFrontOfPlane));
            Assert.IsTrue(distanceToHit == double.PositiveInfinity);
            Assert.IsTrue(!hitFrontOfPlane);

            Ray lookingAtBackOfPlane = new Ray(new Vector3(0, 0, 9), new Vector3(0, 0, 1));
            Assert.IsTrue(testPlane.RayHitPlane(lookingAtBackOfPlane, out distanceToHit, out hitFrontOfPlane));
            Assert.IsTrue(distanceToHit == 1);
            Assert.IsTrue(!hitFrontOfPlane);

            Ray notLookingAtBackOfPlane = new Ray(new Vector3(0, 0, 9), new Vector3(0, 0, -1));
            Assert.IsTrue(!testPlane.RayHitPlane(notLookingAtBackOfPlane, out distanceToHit, out hitFrontOfPlane));
            Assert.IsTrue(distanceToHit == double.PositiveInfinity);
            Assert.IsTrue(hitFrontOfPlane);
        }
		private Ray GetRandomIntersectingRay()
		{
			double maxDist = 1000000;
			Vector3 origin = new Vector3(
				(rayOriginRand.NextDouble() * 2 - 1) * maxDist,
				(rayOriginRand.NextDouble() * 2 - 1) * maxDist,
				(rayOriginRand.NextDouble() * 2 - 1) * maxDist);
			Vector3 direction = Vector3.Normalize(-origin);
			Ray randomRay = new Ray(origin, direction, 0, double.MaxValue);
			return randomRay;
		}
Beispiel #5
0
		public IntersectInfo GetClosestIntersection(Ray ray)
		{
			if (child != null)
			{
				Ray localRay = GetLocalSpaceRay(ray);
				IntersectInfo localIntersection = child.GetClosestIntersection(localRay);
				IntersectInfo globalIntersection = GetGlobalSpaceInfo(localIntersection);
				return globalIntersection;
			}

			return null;
		}
Beispiel #6
0
		public Ray(Ray rayToCopy)
		{
			origin = rayToCopy.origin;
			directionNormal = rayToCopy.directionNormal;
			minDistanceToConsider = rayToCopy.minDistanceToConsider;
			maxDistanceToConsider = rayToCopy.maxDistanceToConsider;
			oneOverDirection = rayToCopy.oneOverDirection;
			isShadowRay = rayToCopy.isShadowRay;
			intersectionType = rayToCopy.intersectionType;
			sign[0] = rayToCopy.sign[0];
			sign[1] = rayToCopy.sign[1];
			sign[2] = rayToCopy.sign[2];
		}
		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;
		}
Beispiel #8
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;
		}
Beispiel #9
0
		public IntersectInfo GetClosestIntersection(Ray ray)
		{
			List<IntersectInfo> allPrimary = new List<IntersectInfo>();
			Ray checkFrontAndBacks = new Ray(ray);
			checkFrontAndBacks.intersectionType = IntersectionType.Both;
			foreach (IntersectInfo info in primary.IntersectionIterator(checkFrontAndBacks))
			{
				allPrimary.Add(info);
			}

			if (allPrimary.Count == 0)
			{
				// We did not hit the primary object.  We are done. The subtract object does not mater.
				return null;
			}

			allPrimary.Sort(new CompareIntersectInfoOnDistance());

			// we hit the primary object, did we hit the subtract object before (within error) hitting the primary.
			List<IntersectInfo> allSubtract = new List<IntersectInfo>();
			foreach (IntersectInfo info in subtract.IntersectionIterator(checkFrontAndBacks))
			{
				allSubtract.Add(info);
			}

			if (allSubtract.Count == 0)
			{
				// we did not hit the subtract so return the first primary
				return allPrimary[0];
			}

			allSubtract.Sort(new CompareIntersectInfoOnDistance());

			List<IntersectInfo> result = new List<IntersectInfo>();
			IntersectInfo.Subtract(allPrimary, allSubtract, result);

			if (result.Count > 0)
			{
				return result[0];
			}

			return null;
		}
		public void SetPrintLevelingEquation(Vector3 position0, Vector3 position1, Vector3 position2, Vector2 bedCenter)
		{
			if (position0 == position1 || position1 == position2 || position2 == position0)
			{
				return;
			}

			Plane planeOfPoints = new Plane(position0, position1, position2);

			Ray ray = new Ray(new Vector3(bedCenter, 0), Vector3.UnitZ);
			bool inFront;
			double distanceToPlaneAtBedCenter = planeOfPoints.GetDistanceToIntersection(ray, out inFront);

			Matrix4X4 makePointsFlatMatrix = Matrix4X4.CreateTranslation(-bedCenter.x, -bedCenter.y, -distanceToPlaneAtBedCenter);
			makePointsFlatMatrix *= Matrix4X4.CreateRotation(planeOfPoints.PlaneNormal, Vector3.UnitZ);
			makePointsFlatMatrix *= Matrix4X4.CreateTranslation(bedCenter.x, bedCenter.y, 0);//distanceToPlaneAtBedCenter);

			bedLevelMatrix = Matrix4X4.Invert(makePointsFlatMatrix);
		}
Beispiel #11
0
		private IntersectInfo FindNextIntersections(IPrimitive element, Ray ray, IntersectInfo info, IntersectionType intersectionType)
		{
			// get all the intersection for the object
			Ray currentRayCheckBackfaces = new Ray(ray);
			currentRayCheckBackfaces.intersectionType = intersectionType;
			currentRayCheckBackfaces.minDistanceToConsider = ((info.hitPosition + ray.directionNormal * Ray.sameSurfaceOffset) - ray.origin).Length;
			currentRayCheckBackfaces.maxDistanceToConsider = double.PositiveInfinity;

			return element.GetClosestIntersection(currentRayCheckBackfaces);
		}
Beispiel #12
0
		public IEnumerable IntersectionIterator(Ray ray)
		{
			List<IntersectInfo> allPrimary = new List<IntersectInfo>();
			Ray checkFrontAndBacks = new Ray(ray);
			checkFrontAndBacks.intersectionType = IntersectionType.Both;
			foreach (IntersectInfo info in primary.IntersectionIterator(checkFrontAndBacks))
			{
				allPrimary.Add(info);
			}

			if (allPrimary.Count == 0)
			{
				// We did not hit the primary object.  We are done. The subtract object does not mater.
				//yield break;
			}

			allPrimary.Sort(new CompareIntersectInfoOnDistance());

			// we hit the primary object, did we hit the subtract object before (within error) hitting the primary.
			List<IntersectInfo> allSubtract = new List<IntersectInfo>();
			foreach (IntersectInfo info in subtract.IntersectionIterator(checkFrontAndBacks))
			{
				allSubtract.Add(info);
			}

			if (allSubtract.Count == 0)
			{
				// we did not hit the subtract so return the primary
				foreach (IntersectInfo primaryInfo in allPrimary)
				{
					yield return primaryInfo;
				}

				yield break;
			}

			allSubtract.Sort(new CompareIntersectInfoOnDistance());

			List<IntersectInfo> results = new List<IntersectInfo>();
			IntersectInfo.Subtract(allPrimary, allSubtract, results);

			foreach (IntersectInfo resultInfo in results)
			{
				yield return resultInfo;
			}
		}
Beispiel #13
0
		public void DifferenceTestsForBox()
		{
			SolidMaterial redMaterial = new SolidMaterial(RGBA_Floats.Red, 0, 0, 0);
			SolidMaterial blueMaterial = new SolidMaterial(RGBA_Floats.Blue, 0, 0, 0);
			Ray castRay = new Ray(new Vector3(0, -1, 0), Vector3.UnitY);

			BoxShape box1X1 = new BoxShape(new Vector3(-.5, -.5, -.5), new Vector3(.5, .5, .5), blueMaterial);

			// just a box all by itself
			{
				IntersectInfo testInfo = box1X1.GetClosestIntersection(castRay);

				Assert.IsTrue(testInfo.hitType == IntersectionType.FrontFace, "Found Hit : Box No CSG");
				Assert.IsTrue(testInfo.closestHitObject == box1X1, "Found Hit : Box No CSG");
				Assert.IsTrue(testInfo.hitPosition == new Vector3(0, -.5, 0), "Hit position y = -.5 : Box No CSG");
				Assert.IsTrue(testInfo.distanceToHit == .5, "Hit length = .5 : Box No CSG");
				Assert.IsTrue(testInfo.normalAtHit == -Vector3.UnitY, "Normal Correct : Box No CSG");
			}

			// one subtract from the front of a box, the front faces are aligned
			{
				BoxShape subtractBox = new BoxShape(new Vector3(-.5, -.5, -.5), new Vector3(.5, 0, .5), redMaterial);
				Difference merge = new Difference(box1X1, subtractBox);
				IntersectInfo testInfo = merge.GetClosestIntersection(castRay);

				Assert.IsTrue(testInfo.hitType == IntersectionType.FrontFace, "Found Hit : One Subtract");
				Assert.IsTrue(testInfo.closestHitObject == subtractBox, "Found Hit : One Subtract");
				Assert.IsTrue(testInfo.hitPosition == new Vector3(0, 0, 0), "Hit position y = 0 : One Subtract");
				Assert.IsTrue(testInfo.distanceToHit == 1, "Hit length = 1 : One Subtract");
				Assert.IsTrue(testInfo.normalAtHit == -Vector3.UnitY, "Normal Correct : One Subtract");
			}

#if false
            // An internal primary object that needs to be skipped over
            {
                List<IPrimitive> primaryShapes = new List<IPrimitive>();
                BoxShape insideBox = new BoxShape(new Vector3(-.1, -.1, -.1), new Vector3(.1, .1, .1), blueMaterial);
                primaryShapes.Add(box1X1);
                primaryShapes.Add(insideBox);
                IPrimitive primamryGroup = BoundingVolumeHierarchy.CreateNewHierachy(primaryShapes);

                List<IPrimitive> subtractShapes = new List<IPrimitive>();
                subtractShapes.Add(new BoxShape(new Vector3(-.5, -.5, -.5), new Vector3(.5, .4, .5), redMaterial));

                IPrimitive subtractGroup = BoundingVolumeHierarchy.CreateNewHierachy(subtractShapes);
                Difference merge = new Difference(primamryGroup, subtractGroup);

                IntersectInfo testInfo = merge.GetClosestIntersection(castRay);

                Assert.IsTrue(testInfo.isHit == true, "Found Hit : 5 Subtracts");
                //Assert.IsTrue(testInfo.closestHitObject == subtractBox, "Found Hit : 5 Subtracts");
                Assert.IsTrue(testInfo.hitPosition == new Vector3(0, 0, 0), "Hit position y = 0 : 5 Subtracts");
                Assert.IsTrue(testInfo.distanceToHit == 1, "Hit length = 1 : 5 Subtracts");
                Assert.IsTrue(testInfo.normalAtHit == -Vector3.UnitY, "Normal Correct : 5 Subtracts");
            }

            // Go through 5 subtract boxes to get to 1/2 way through the main box.
            {
                List<IPrimitive> subtractShapes = new List<IPrimitive>();

                for (int i = 0; i < 5; i++)
                {
                    subtractShapes.Add(new BoxShape(new Vector3(-.5, -.5 + i * .1, -.5), new Vector3(.5, -.4 + i * .1, .5), redMaterial));
                }

                IPrimitive subtractGroup = BoundingVolumeHierarchy.CreateNewHierachy(subtractShapes);
                Difference merge = new Difference(box1X1, subtractGroup);

                IntersectInfo testInfo = merge.GetClosestIntersection(castRay);

                Assert.IsTrue(testInfo.isHit == true, "Found Hit : 5 Subtracts");
                //Assert.IsTrue(testInfo.closestHitObject == subtractBox, "Found Hit : 5 Subtracts");
                Assert.IsTrue(testInfo.hitPosition == new Vector3(0, 0, 0), "Hit position y = 0 : 5 Subtracts");
                Assert.IsTrue(testInfo.distanceToHit == 1, "Hit length = 1 : 5 Subtracts");
                Assert.IsTrue(testInfo.normalAtHit == -Vector3.UnitY, "Normal Correct : 5 Subtracts");
            }
#endif
		}
Beispiel #14
0
		public bool GetCutLine(Plane cutPlane, out Vector3 start, out Vector3 end)
		{
			start = new Vector3();
			end = new Vector3();
			int splitCount = 0;
			FaceEdge prevEdge = null;
			bool prevInFront = false;
			bool first = true;
			FaceEdge firstEdge = null;
			bool firstInFront = false;
			foreach (FaceEdge faceEdge in FaceEdges())
			{
				if (first)
				{
					prevEdge = faceEdge;
					prevInFront = cutPlane.GetDistanceFromPlane(prevEdge.firstVertex.Position) > 0;
					first = false;
					firstEdge = prevEdge;
					firstInFront = prevInFront;
				}
				else
				{
					FaceEdge curEdge = faceEdge;
					bool curInFront = cutPlane.GetDistanceFromPlane(curEdge.firstVertex.Position) > 0;
					if (prevInFront != curInFront)
					{
						// we crossed over the cut line
						Vector3 directionNormal = (curEdge.firstVertex.Position - prevEdge.firstVertex.Position).GetNormal();
						Ray edgeRay = new Ray(prevEdge.firstVertex.Position, directionNormal);
						double distanceToHit;
						bool hitFrontOfPlane;
						if (cutPlane.RayHitPlane(edgeRay, out distanceToHit, out hitFrontOfPlane))
						{
							splitCount++;
							if (splitCount == 1)
							{
								start = edgeRay.origin + edgeRay.directionNormal * distanceToHit;
							}
							else
							{
								end = edgeRay.origin + edgeRay.directionNormal * distanceToHit;
							}
						}
					}

					prevEdge = curEdge;
					prevInFront = curInFront;
					if (splitCount == 2)
					{
						break;
					}
				}
			}

			if (splitCount == 1
				&& prevInFront != firstInFront)
			{
				// we crossed over the cut line
				Vector3 directionNormal = (firstEdge.firstVertex.Position - prevEdge.firstVertex.Position).GetNormal();
				Ray edgeRay = new Ray(prevEdge.firstVertex.Position, directionNormal);
				double distanceToHit;
				bool hitFrontOfPlane;
				if (cutPlane.RayHitPlane(edgeRay, out distanceToHit, out hitFrontOfPlane))
				{
					splitCount++;
					end = edgeRay.origin + edgeRay.directionNormal * distanceToHit;
				}
			}

			if (splitCount == 2)
			{
				return true;
			}

			return false;
		}
Beispiel #15
0
 Ray GetLocalSpaceRay(Ray ray)
 {
     // TODO: cache this.
     Matrix4X4 WorldToAxis = Matrix4X4.Invert(AxisToWorld);
     Vector3 transformedOrigin = Vector3.TransformPosition(ray.origin, WorldToAxis);
     Vector3 transformedDirecton = Vector3.TransformVector(ray.direction, WorldToAxis);
     return new Ray(transformedOrigin, transformedDirecton, ray.minDistanceToConsider, ray.maxDistanceToConsider, ray.intersectionType);
 }
		public IEnumerable IntersectionIterator(Ray ray)
		{
			foreach (IPrimitive item in items)
			{
				foreach (IntersectInfo info in item.IntersectionIterator(ray))
				{
					yield return info;
				}
			}
		}
Beispiel #17
0
        public override IntersectInfo GetClosestIntersection(Ray ray)
        {
            double radiusSquared = radius * radius;

            Vector2 rayOrigin = new Vector2(ray.origin);
            Vector2 rayDirectionXY = new Vector2(ray.direction);
            Vector2 rayDirection = rayDirectionXY.GetNormal();
            Vector2 thisPosition = Vector2.Zero;
            Vector2 deltaFromShpereCenterToRayOrigin = rayOrigin - thisPosition;
            double distanceFromCircleCenterToRayOrigin = Vector2.Dot(deltaFromShpereCenterToRayOrigin, rayDirection); // negative means the Circle is in front of the ray.
            double lengthFromRayOrginToCircleCenterSquared = Vector2.Dot(deltaFromShpereCenterToRayOrigin, deltaFromShpereCenterToRayOrigin);
            double lengthFromRayOrigintoNearEdgeOfCircleSquared = lengthFromRayOrginToCircleCenterSquared - radiusSquared;
            double distanceFromCircleCenterToRaySquared = distanceFromCircleCenterToRayOrigin * distanceFromCircleCenterToRayOrigin;
            double amountCircleCenterToRayIsGreaterThanRayOriginToEdgeSquared = distanceFromCircleCenterToRaySquared - lengthFromRayOrigintoNearEdgeOfCircleSquared;

            if (amountCircleCenterToRayIsGreaterThanRayOriginToEdgeSquared > 0)
            {
                {
                    bool inFrontOfTop;
                    double testDistanceToHit = topPlane.GetDistanceToIntersection(ray, out inFrontOfTop);
                    bool wantFrontAndInFront = (ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace && inFrontOfTop;
                    bool wantBackAndInBack = (ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace && !inFrontOfTop;
                    if (wantFrontAndInFront || wantBackAndInBack)
                    {
                        Vector3 topHitPosition = ray.origin + ray.direction * testDistanceToHit;

                        if (topHitPosition.x * topHitPosition.x + topHitPosition.y * topHitPosition.y < topRadius * topRadius)
                        {
                            IntersectInfo topHitInfo = new IntersectInfo();
                            topHitInfo.hitPosition = topHitPosition;
                            topHitInfo.closestHitObject = this;
                            if (ray.intersectionType == IntersectionType.FrontFace)
                            {
                                topHitInfo.hitType = IntersectionType.FrontFace;
                                topHitInfo.normalAtHit = topPlane.planeNormal;
                            }
                            else
                            {
                                topHitInfo.hitType = IntersectionType.BackFace;
                                topHitInfo.normalAtHit = -topPlane.planeNormal;
                            }
                            topHitInfo.distanceToHit = testDistanceToHit;

                            return topHitInfo;
                        }
                    }
                }

                {
                    bool inFrontOfBottom;
                    double testDistanceToHit = bottomPlane.GetDistanceToIntersection(ray, out inFrontOfBottom);
                    if (ray.intersectionType == IntersectionType.FrontFace && inFrontOfBottom
                        || ray.intersectionType == IntersectionType.BackFace && !inFrontOfBottom)
                    {
                        Vector3 bottomHitPosition = ray.origin + ray.direction * testDistanceToHit;

                        if (bottomHitPosition.x * bottomHitPosition.x + bottomHitPosition.y * bottomHitPosition.y < radius * radius)
                        {
                            IntersectInfo bottomHitInfo = new IntersectInfo();
                            bottomHitInfo.hitPosition = bottomHitPosition;
                            bottomHitInfo.closestHitObject = this;
                            if (ray.intersectionType == IntersectionType.FrontFace)
                            {
                                bottomHitInfo.hitType = IntersectionType.FrontFace;
                                bottomHitInfo.normalAtHit = bottomPlane.planeNormal;
                            }
                            else
                            {
                                bottomHitInfo.hitType = IntersectionType.BackFace;
                                bottomHitInfo.normalAtHit = -bottomPlane.planeNormal;
                            }
                            bottomHitInfo.distanceToHit = testDistanceToHit;

                            return bottomHitInfo;
                        }
                    }
                }

                IntersectInfo info = new IntersectInfo();
                info.closestHitObject = this;
                info.hitType = IntersectionType.FrontFace;
                if (ray.isShadowRay)
                {
                    return info;
                }
                double distanceFromRayOriginToCircleCenter = -distanceFromCircleCenterToRayOrigin;

                double amountCircleCenterToRayIsGreaterThanRayOriginToEdge = Math.Sqrt(amountCircleCenterToRayIsGreaterThanRayOriginToEdgeSquared);

                double scaleRatio = ray.direction.Length / rayDirectionXY.Length;

                if (ray.intersectionType == IntersectionType.FrontFace)
                {
                    double distanceToFrontHit = (distanceFromRayOriginToCircleCenter - amountCircleCenterToRayIsGreaterThanRayOriginToEdge) * scaleRatio;
                    if (distanceToFrontHit > ray.maxDistanceToConsider || distanceToFrontHit < ray.minDistanceToConsider)
                    {
                        return null;
                    }
                    info.distanceToHit = distanceToFrontHit;
                    info.hitPosition = ray.origin + ray.direction * info.distanceToHit;
                    if (info.hitPosition.z < -height / 2 || info.hitPosition.z > height / 2)
                    {
                        return null;
                    }
                    info.normalAtHit = new Vector3(info.hitPosition.x, info.hitPosition.y, 0).GetNormal();
                }
                else if (ray.intersectionType == IntersectionType.BackFace)// check back faces
                {
                    double distanceToBackHit = (distanceFromRayOriginToCircleCenter + amountCircleCenterToRayIsGreaterThanRayOriginToEdge) * scaleRatio;
                    if (distanceToBackHit > ray.maxDistanceToConsider || distanceToBackHit < ray.minDistanceToConsider)
                    {
                        return null;
                    }
                    info.hitType = IntersectionType.BackFace;
                    info.distanceToHit = distanceToBackHit;
                    info.hitPosition = ray.origin + ray.direction * info.distanceToHit;
                    if (info.hitPosition.z < height / 2 || info.hitPosition.z > height / 2)
                    {
                        return null;
                    }
                    info.normalAtHit = -(new Vector3(info.hitPosition.x, info.hitPosition.y, 0).GetNormal());
                }

                return info;
            }

            return null;
        }
Beispiel #18
0
        public override IEnumerable IntersectionIterator(Ray ray)
        {
            double radiusSquared = radius * radius;

            Vector2 rayOrigin = new Vector2(ray.origin);
            Vector2 rayDirectionXY = new Vector2(ray.direction);
            Vector2 rayDirection = rayDirectionXY.GetNormal();
            Vector2 thisPosition = Vector2.Zero;
            Vector2 deltaFromShpereCenterToRayOrigin = rayOrigin - thisPosition;
            double distanceFromCircleCenterToRayOrigin = Vector2.Dot(deltaFromShpereCenterToRayOrigin, rayDirection);
            double lengthFromRayOrginToCircleCenterSquared = Vector2.Dot(deltaFromShpereCenterToRayOrigin, deltaFromShpereCenterToRayOrigin);
            double lengthFromRayOrigintoNearEdgeOfCircleSquared = lengthFromRayOrginToCircleCenterSquared - radiusSquared;
            double distanceFromCircleCenterToRaySquared = distanceFromCircleCenterToRayOrigin * distanceFromCircleCenterToRayOrigin;
            double amountCircleCenterToRayIsGreaterThanRayOriginToEdgeSquared = distanceFromCircleCenterToRaySquared - lengthFromRayOrigintoNearEdgeOfCircleSquared;

            if (amountCircleCenterToRayIsGreaterThanRayOriginToEdgeSquared > 0)
            {
                double distanceFromRayOriginToCircleCenter = -distanceFromCircleCenterToRayOrigin;
                double amountCircleCenterToRayIsGreaterThanRayOriginToEdge = Math.Sqrt(amountCircleCenterToRayIsGreaterThanRayOriginToEdgeSquared);
                double scaleRatio = ray.direction.Length / rayDirectionXY.Length;

                if ((ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace)
                {
                    IntersectInfo info = new IntersectInfo();
                    info.hitType = IntersectionType.FrontFace;
                    info.closestHitObject = this;
                    double distanceToFrontHit = (distanceFromRayOriginToCircleCenter - amountCircleCenterToRayIsGreaterThanRayOriginToEdge) * scaleRatio;
                    info.distanceToHit = distanceToFrontHit;
                    info.hitPosition = ray.origin + ray.direction * info.distanceToHit;
                    if (info.hitPosition.z > -height / 2 && info.hitPosition.z < height / 2)
                    {
                        info.normalAtHit = new Vector3(info.hitPosition.x, info.hitPosition.y, 0).GetNormal();
                        yield return info;
                    }
                }


                if ((ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace)
                {
                    IntersectInfo info = new IntersectInfo();
                    info.hitType = IntersectionType.BackFace;
                    info.closestHitObject = this;
                    double distanceToBackHit = (distanceFromRayOriginToCircleCenter + amountCircleCenterToRayIsGreaterThanRayOriginToEdge) * scaleRatio;
                    info.distanceToHit = distanceToBackHit;
                    info.hitPosition = ray.origin + ray.direction * info.distanceToHit;
                    if (info.hitPosition.z > -height / 2 && info.hitPosition.z < height / 2)
                    {
                        info.normalAtHit = -(new Vector3(info.hitPosition.x, info.hitPosition.y, 0).GetNormal());
                        yield return info;
                    }
                }

                {
                    bool inFrontOfTopFace;
                    double testDistanceToHit = topPlane.GetDistanceToIntersection(ray, out inFrontOfTopFace);
                    Vector3 topHitPosition = ray.origin + ray.direction * testDistanceToHit;

                    if (topHitPosition.x * topHitPosition.x + topHitPosition.y * topHitPosition.y < topRadius * topRadius)
                    {
                        if ((ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace && inFrontOfTopFace)
                        {
                            IntersectInfo topHitInfo = new IntersectInfo();
                            topHitInfo.hitPosition = topHitPosition;
                            topHitInfo.closestHitObject = this;
                            topHitInfo.hitType = IntersectionType.FrontFace;
                            topHitInfo.normalAtHit = topPlane.planeNormal;
                            topHitInfo.distanceToHit = testDistanceToHit;

                            yield return topHitInfo;
                        }

                        if ((ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace && !inFrontOfTopFace)
                        {
                            IntersectInfo topHitInfo = new IntersectInfo();
                            topHitInfo.hitPosition = topHitPosition;
                            topHitInfo.closestHitObject = this;
                            topHitInfo.hitType = IntersectionType.BackFace;
                            topHitInfo.normalAtHit = -topPlane.planeNormal;
                            topHitInfo.distanceToHit = testDistanceToHit;

                            yield return topHitInfo;
                        }
                    }
                }

                {
                    bool inFrontOfBottomFace;
                    double testDistanceToHit = bottomPlane.GetDistanceToIntersection(ray, out inFrontOfBottomFace);
                    Vector3 bottomHitPosition = ray.origin + ray.direction * testDistanceToHit;

                    if (bottomHitPosition.x * bottomHitPosition.x + bottomHitPosition.y * bottomHitPosition.y < radius * radius)
                    {
                        if ((ray.intersectionType & IntersectionType.FrontFace) == IntersectionType.FrontFace && inFrontOfBottomFace)
                        {
                            IntersectInfo bottomHitInfo = new IntersectInfo();
                            bottomHitInfo.hitPosition = bottomHitPosition;
                            bottomHitInfo.closestHitObject = this;
                            bottomHitInfo.hitType = IntersectionType.FrontFace;
                            bottomHitInfo.normalAtHit = bottomPlane.planeNormal;
                            bottomHitInfo.distanceToHit = testDistanceToHit;

                            yield return bottomHitInfo;
                        }

                        if ((ray.intersectionType & IntersectionType.BackFace) == IntersectionType.BackFace && !inFrontOfBottomFace)
                        {
                            IntersectInfo bottomHitInfo = new IntersectInfo();
                            bottomHitInfo.hitPosition = bottomHitPosition;
                            bottomHitInfo.closestHitObject = this;
                            bottomHitInfo.hitType = IntersectionType.BackFace;
                            bottomHitInfo.normalAtHit = -bottomPlane.planeNormal;
                            bottomHitInfo.distanceToHit = testDistanceToHit;

                            yield return bottomHitInfo;
                        }
                    }
                }
            }
        }
		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;
						}
					}
				}
			}
		}
Beispiel #20
0
		public abstract IEnumerable IntersectionIterator(Ray ray);
Beispiel #21
0
		public abstract IntersectInfo GetClosestIntersection(Ray ray);
		public MouseEvent3DArgs(MouseEventArgs mouseEvent2D, Ray mouseRay, IntersectInfo info)
		{
			this.info = info;
			this.MouseEvent2D = mouseEvent2D;
			this.mouseRay = mouseRay;
		}
Beispiel #23
0
		public override IEnumerable IntersectionIterator(Ray ray)
		{
			double radiusSquared = radius * radius;

			Vector3 deltaFromShpereCenterToRayOrigin = ray.origin - this.position;
			double distanceFromSphereCenterToRayOrigin = Vector3.Dot(deltaFromShpereCenterToRayOrigin, ray.directionNormal); // negative means the sphere is in front of the ray.
			double lengthFromRayOrginToSphereCenterSquared = Vector3.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;
				}
			}
		}
		private bool FindInteractionVolumeHit(Ray ray, out int interactionVolumeHitIndex, out IntersectInfo info)
		{
			interactionVolumeHitIndex = -1;
			if (interactionVolumes.Count == 0 || interactionVolumes[0].CollisionVolume == null)
			{
				info = null;
				return false;
			}

			List<IPrimitive> mesheTraceables = new List<IPrimitive>();
			foreach (InteractionVolume interactionVolume in interactionVolumes)
			{
				IPrimitive traceData = interactionVolume.CollisionVolume;
				mesheTraceables.Add(new Transform(traceData, interactionVolume.TotalTransform));
			}
			IPrimitive allObjects = BoundingVolumeHierarchy.CreateNewHierachy(mesheTraceables);

			info = allObjects.GetClosestIntersection(ray);
			if (info != null)
			{
				for (int i = 0; i < interactionVolumes.Count; i++)
				{
					List<IPrimitive> insideBounds = new List<IPrimitive>();
					interactionVolumes[i].CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox());
					if (insideBounds.Contains(info.closestHitObject))
					{
						interactionVolumeHitIndex = i;
						return true;
					}
				}
			}

			return false;
		}
Beispiel #25
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 = Vector3.Dot(deltaFromShpereCenterToRayOrigin, ray.directionNormal); // negative means the sphere is in front of the ray.
			double lengthFromRayOrginToSphereCenterSquared = Vector3.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;
		}
Beispiel #26
0
        public Ray GetRay(double screenX, double screenY)
        {
            Vector3 origin = Origin;
            Vector3 direction = GetDirectionMinus1To1(screenX, screenY);

            direction = Vector3.TransformVector(direction, axisToWorld);

            Ray ray = new Ray(origin, direction);
            return ray;
        }
		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;
		}
Beispiel #28
0
 public IEnumerable IntersectionIterator(Ray ray)
 {
     Ray localRay = GetLocalSpaceRay(ray);
     foreach (IntersectInfo localInfo in child.IntersectionIterator(localRay))
     {
         IntersectInfo globalIntersection = GetGlobalSpaceInfo(localInfo);
         yield return globalIntersection;
     }
 }
Beispiel #29
0
        public double GetDistanceToIntersection(Ray ray, out bool inFront)
        {
            inFront = false;
            double normalDotRayDirection = Vector3.Dot(planeNormal, ray.direction);
            if (normalDotRayDirection < TreatAsZero && normalDotRayDirection > -TreatAsZero) // the ray is parallel to the plane
            {
                return double.PositiveInfinity;
            }

            if (normalDotRayDirection < 0)
            {
                inFront = true;
            }

            return (distanceToPlaneFromOrigin - Vector3.Dot(planeNormal, ray.origin)) / normalDotRayDirection;
        }
Beispiel #30
0
		public override IEnumerable IntersectionIterator(Ray ray)
		{
			throw new NotImplementedException();
		}