Example #1
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            // find the ray for this control
            // check what face it hits
            // mark that face to draw a highlight
            base.OnMouseMove(mouseEvent);

            // rotate the view
            if (MouseDownOnWidget)
            {
                var        movePosition             = mouseEvent.Position;
                Quaternion activeRotationQuaternion = TrackBallController.GetRotationForMove(new Vector2(Width / 2, Height / 2), world, Width, lastMovePosition, movePosition, false);

                if (activeRotationQuaternion != Quaternion.Identity)
                {
                    lastMovePosition = movePosition;
                    interactionLayer.World.RotationMatrix = interactionLayer.World.RotationMatrix * Matrix4X4.CreateRotation(activeRotationQuaternion);
                    interactionLayer.Invalidate();
                }
            }
            else if (world != null &&
                     cubeTraceData != null)               // Make sure we don't use the trace data before it is ready
            {
                Ray           ray  = world.GetRayForLocalBounds(mouseEvent.Position);
                IntersectInfo info = cubeTraceData.GetClosestIntersection(ray);

                if (info != null)
                {
                    var uV = ((TriangleShapeUv)info.closestHitObject).GetUv(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);
        }
Example #3
0
        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);
        }
Example #4
0
		private long CalculateIntersectCostsForItem(IPrimitive item, int numInterations)
		{
			Stopwatch timer = new Stopwatch();
			timer.Start();
			for (int i = 0; i < numInterations; i++)
			{
				item.GetClosestIntersection(GetRandomIntersectingRay());
			}
			return timer.ElapsedMilliseconds;
		}
Example #5
0
        private long CalculateIntersectCostsForItem(IPrimitive item, int numInterations)
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();
            for (int i = 0; i < numInterations; i++)
            {
                item.GetClosestIntersection(GetRandomIntersectingRay());
            }
            return(timer.ElapsedMilliseconds);
        }
Example #6
0
        private bool FindInteractionVolumeHit(Ray ray, out InteractionVolume hitIAVolume, out IntersectInfo info)
        {
            var iaVolumes = this.InteractionVolumes;

            hitIAVolume = null;

            if (!iaVolumes.Any())
            {
                info = null;
                return(false);
            }

            // TODO: Rewrite as projection without extra list
            // - Looks like the extra list is always required as CreateNewHierachy requires a List and we can only produce an IEnumerable without the list overhead
            // - var uiTraceables = iaVolumes.Where(ia => ia.CollisionVolume != null).Select(ia => new Transform(ia.CollisionVolume, ia.TotalTransform)).ToList<IPrimitive>();
            var uiTraceables = new List <IPrimitive>();

            foreach (var interactionVolume in iaVolumes.OfType <InteractionVolume>())
            {
                if (interactionVolume.CollisionVolume != null)
                {
                    IPrimitive traceData = interactionVolume.CollisionVolume;
                    uiTraceables.Add(new Transform(traceData, interactionVolume.TotalTransform));
                }
            }

            if (uiTraceables.Count <= 0)
            {
                info = null;
                return(false);
            }

            IPrimitive allUiObjects = BoundingVolumeHierarchy.CreateNewHierachy(uiTraceables);

            info = allUiObjects.GetClosestIntersection(ray);
            if (info != null)
            {
                foreach (var iaVolume in iaVolumes.OfType <InteractionVolume>())
                {
                    var insideBounds = new List <IBvhItem>();
                    if (iaVolume.CollisionVolume != null)
                    {
                        iaVolume.CollisionVolume.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox());
                        if (insideBounds.Contains(info.closestHitObject))
                        {
                            hitIAVolume = iaVolume;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Example #7
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));
        }
Example #8
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);
        }
        private bool FindMeshGroupHitPosition(Vector2 screenPosition, out int meshHitIndex)
        {
            meshHitIndex = 0;
            if (MeshGroupExtraData.Count == 0 || MeshGroupExtraData[0].meshTraceableData == null)
            {
                return(false);
            }

            List <IPrimitive> mesheTraceables = new List <IPrimitive>();

            for (int i = 0; i < MeshGroupExtraData.Count; i++)
            {
                foreach (IPrimitive traceData in MeshGroupExtraData[i].meshTraceableData)
                {
                    mesheTraceables.Add(new Transform(traceData, MeshGroupTransforms[i].TotalTransform));
                }
            }
            IPrimitive allObjects = BoundingVolumeHierarchy.CreateNewHierachy(mesheTraceables);

            Vector2       meshViewerWidgetScreenPosition = meshViewerWidget.TransformFromParentSpace(this, screenPosition);
            Ray           ray  = meshViewerWidget.TrackballTumbleWidget.GetRayFromScreen(meshViewerWidgetScreenPosition);
            IntersectInfo info = allObjects.GetClosestIntersection(ray);

            if (info != null)
            {
                meshSelectInfo.planeDownHitPos = info.hitPosition;
                meshSelectInfo.lastMoveDelta   = new Vector3();

                for (int i = 0; i < MeshGroupExtraData.Count; i++)
                {
                    List <IPrimitive> insideBounds = new List <IPrimitive>();
                    foreach (IPrimitive traceData in MeshGroupExtraData[i].meshTraceableData)
                    {
                        traceData.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox());
                    }
                    if (insideBounds.Contains(info.closestHitObject))
                    {
                        meshHitIndex = i;
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #10
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);
		}
        private bool FindMeshGroupHitPosition(Vector2 screenPosition, out int meshHitIndex, ref IntersectInfo info)
		{
			meshHitIndex = 0;
			if (MeshGroupExtraData.Count == 0 || MeshGroupExtraData[0].meshTraceableData == null)
			{
				return false;
			}

			List<IPrimitive> mesheTraceables = new List<IPrimitive>();
			for (int i = 0; i < MeshGroupExtraData.Count; i++)
			{
				foreach (IPrimitive traceData in MeshGroupExtraData[i].meshTraceableData)
				{
					mesheTraceables.Add(new Transform(traceData, MeshGroupTransforms[i]));
				}
			}
			allObjects = BoundingVolumeHierarchy.CreateNewHierachy(mesheTraceables, 0);

			Vector2 meshViewerWidgetScreenPosition = meshViewerWidget.TransformFromParentSpace(this, screenPosition);
			Ray ray = meshViewerWidget.TrackballTumbleWidget.GetRayFromScreen(meshViewerWidgetScreenPosition);
			info = allObjects.GetClosestIntersection(ray);
			if (info != null)
			{
				CurrentSelectInfo.PlaneDownHitPos = info.hitPosition;
				CurrentSelectInfo.LastMoveDelta = new Vector3();

				for (int i = 0; i < MeshGroupExtraData.Count; i++)
				{
					List<IPrimitive> insideBounds = new List<IPrimitive>();
					foreach (IPrimitive traceData in MeshGroupExtraData[i].meshTraceableData)
					{
						traceData.GetContained(insideBounds, info.closestHitObject.GetAxisAlignedBoundingBox());
					}
					if (insideBounds.Contains(info.closestHitObject))
					{
						meshHitIndex = i;
						return true;
					}
				}
			}

			return false;
		}