Exemplo n.º 1
0
        public override void OnMouseUp(MouseEventArgs mouseEvent)
        {
            base.OnMouseUp(mouseEvent);

            trackballTumbleWidgetExtended.EndRotateAroundOrigin();

            if (mouseEvent.Button != MouseButtons.Left)
            {
                return;
            }

            // Make sure we don't use the trace data before it is ready
            if (mouseDownPosition == mouseEvent.Position &&
                cubeTraceData != null)
            {
                Ray           ray  = world.GetRayForLocalBounds(mouseEvent.Position);
                IntersectInfo info = cubeTraceData.GetClosestIntersection(ray);

                if (info != null)
                {
                    var hitData     = GetHitData(info.HitPosition);
                    var normalAndUp = GetDirectionForFace(hitData);

                    var look = Matrix4X4.LookAt(Vector3.Zero, normalAndUp.normal, normalAndUp.up);

                    trackballTumbleWidgetExtended.AnimateRotation(look);
                }
            }

            object3DControlLayer.Focus();
        }
Exemplo n.º 2
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            mouseOver = false;
            // 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)
            {
                trackballTumbleWidgetExtended.DoRotateAroundOrigin(mouseEvent.Position);
            }
            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)
                {
                    mouseOver = true;

                    DrawMouseHover(GetHitData(info.HitPosition));
                }
                else
                {
                    ResetTextures();
                }
            }
        }
        private void ZoomToMousePosition(Vector2 mousePosition, double zoomDelta)
        {
            var           rayAtScreenCenter  = world.GetRayForLocalBounds(new Vector2(Width / 2, Height / 2));
            var           rayAtMousePosition = world.GetRayForLocalBounds(mousePosition);
            IntersectInfo intersectionInfo   = Object3DControlLayer.Scene.GetBVHData().GetClosestIntersection(rayAtMousePosition);

            if (intersectionInfo != null)
            {
                // we hit an object in the scene set the position to that
                hitPlane = new PlaneShape(new Plane(rayAtScreenCenter.directionNormal, mouseDownWorldPosition), null);
                ZoomToWorldPosition(intersectionInfo.HitPosition, zoomDelta);
                mouseDownWorldPosition = intersectionInfo.HitPosition;
            }
            else
            {
                // we did not hit anything
                // find a new 3d mouse position by hitting the screen plane at the distance of the last 3d mouse down position
                hitPlane         = new PlaneShape(new Plane(rayAtScreenCenter.directionNormal, mouseDownWorldPosition), null);
                intersectionInfo = hitPlane.GetClosestIntersection(rayAtMousePosition);
                if (intersectionInfo != null)
                {
                    ZoomToWorldPosition(intersectionInfo.HitPosition, zoomDelta);
                    mouseDownWorldPosition = intersectionInfo.HitPosition;
                }
            }
        }
Exemplo n.º 4
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None && meshSelectInfo.downOnPart)
            {
                Vector2       meshViewerWidgetScreenPosition = meshViewerWidget.TransformFromParentSpace(this, new Vector2(mouseEvent.X, mouseEvent.Y));
                Ray           ray  = meshViewerWidget.TrackballTumbleWidget.GetRayFromScreen(meshViewerWidgetScreenPosition);
                IntersectInfo info = meshSelectInfo.hitPlane.GetClosestIntersection(ray);
                if (info != null)
                {
                    Vector3 delta = info.hitPosition - meshSelectInfo.planeDownHitPos;

                    Matrix4X4 totalTransform = Matrix4X4.CreateTranslation(new Vector3(-meshSelectInfo.lastMoveDelta));
                    totalTransform *= Matrix4X4.CreateTranslation(new Vector3(delta));
                    meshSelectInfo.lastMoveDelta = delta;

                    ScaleRotateTranslate translated = SelectedMeshTransform;
                    translated.translation *= totalTransform;
                    SelectedMeshTransform   = translated;

                    Invalidate();
                }
            }

            base.OnMouseMove(mouseEvent);
        }
Exemplo n.º 5
0
        public IntersectInfo GetClosestIntersection(Ray ray)
        {
            // find the point on the plane
            Vector3[] positions = new Vector3[3];
            int       index     = 0;

            foreach (FaceEdge faceEdge in face.FaceEdges())
            {
                positions[index++] = faceEdge.FirstVertex.Position;
                if (index == 3)
                {
                    break;
                }
            }
            Plane  plane = new Plane(positions[0], positions[1], positions[2]);
            double distanceToHit;
            bool   hitFrontOfPlane;

            if (plane.RayHitPlane(ray, out distanceToHit, out hitFrontOfPlane))
            {
                Vector3 polyPlaneIntersection = ray.origin + ray.directionNormal * distanceToHit;
                if (face.PointInPoly(polyPlaneIntersection))
                {
                    IntersectInfo info = new IntersectInfo();
                    info.closestHitObject = this;
                    info.distanceToHit    = distanceToHit;
                    info.HitPosition      = polyPlaneIntersection;
                    info.normalAtHit      = face.Normal;
                    info.hitType          = IntersectionType.FrontFace;
                    return(info);
                }
            }

            return(null);
        }
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            lastMouseMovePosition = mouseEvent.Position;
            base.OnMouseMove(mouseEvent);

            if (SuppressObject3DControls ||
                !this.PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y) ||
                !CanSelectObject())
            {
                return;
            }

            Ray           ray          = this.World.GetRayForLocalBounds(mouseEvent.Position);
            IntersectInfo info         = null;
            var           mouseEvent3D = new Mouse3DEventArgs(mouseEvent, ray, info);

            if (MouseDownOnObject3DControlVolume && mouseDownObject3DControl != null)
            {
                mouseDownObject3DControl.OnMouseMove(mouseEvent3D, false);
            }
            else
            {
                this.FindHitObject3DControl(ray, out IObject3DControl hitObject3DControl, out _);

                var object3DControls = this.Object3DControls;

                var overControl = false;
                foreach (var object3DControl in object3DControls)
                {
                    if (hitObject3DControl == object3DControl &&
                        hitObject3DControl.Visible)
                    {
                        overControl = true;

                        // we have found the control that got hit, wait 200 ms to see if we are still over the same control
                        UiThread.RunOnIdle(() =>
                        {
                            var ray2 = this.World.GetRayForLocalBounds(lastMouseMovePosition);
                            this.FindHitObject3DControl(ray2, out IObject3DControl stillOver3DControl, out _);

                            if (stillOver3DControl == hitObject3DControl)
                            {
                                // we are over the same control as the last mouse move so set the hovered object to it
                                HoveredObject3DControl = object3DControl;
                                object3DControl.OnMouseMove(mouseEvent3D, true);
                            }
                        }, .2);
                    }
                    else
                    {
                        object3DControl.OnMouseMove(mouseEvent3D, false);
                    }
                }

                if (overControl &&
                    hitObject3DControl is Object3DControl object3DControl2 &&
                    object3DControl2.RootSelection != null)
                {
                    ApplicationController.Instance.UiHint = "Click to edit values".Localize();
                }
Exemplo n.º 7
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);
                }
            }
        }
Exemplo n.º 8
0
        public override void OnMouseMove(MouseEvent3DArgs mouseEvent3D)
        {
            IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

            if (info != null && MeshViewerToDrawWith.SelectedMeshGroupIndex != -1)
            {
                Vector3 delta = new Vector3(0, 0, info.hitPosition.z - zHitHeight);

                // move it back to where it started
                MeshViewerToDrawWith.SelectedMeshGroupTransform *= Matrix4X4.CreateTranslation(new Vector3(-lastMoveDelta));

                if (MeshViewerToDrawWith.SnapGridDistance > 0)
                {
                    // snap this position to the grid
                    double snapGridDistance = MeshViewerToDrawWith.SnapGridDistance;
                    AxisAlignedBoundingBox selectedBounds = MeshViewerToDrawWith.GetBoundsForSelection();

                    // snap the z position
                    double bottom        = selectedBounds.minXYZ.z + delta.z;
                    double snappedBottom = (Math.Round((bottom / snapGridDistance))) * snapGridDistance;
                    delta.z = snappedBottom - selectedBounds.minXYZ.z;
                }

                // and move it from there to where we are now
                MeshViewerToDrawWith.SelectedMeshGroupTransform *= Matrix4X4.CreateTranslation(new Vector3(delta));

                lastMoveDelta = delta;

                view3DWidget.PartHasBeenChanged();
                Invalidate();
            }

            base.OnMouseMove(mouseEvent3D);
        }
Exemplo n.º 9
0
        public override async void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver)
        {
            var selectedItem = RootSelection;

            activeSelectedItem = selectedItem;
            if (MouseIsOver)
            {
                heightValueDisplayInfo.Visible = true;
            }
            else if (!hadClickOnControl)
            {
                heightValueDisplayInfo.Visible = false;
            }

            if (MouseDownOnControl)
            {
                IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

                if (info != null &&
                    selectedItem != null)
                {
                    var delta = info.HitPosition - initialHitPosition;

                    var bottom = GetBottomPosition(selectedItem);
                    var top    = GetTopPosition(selectedItem);

                    var up = top - bottom;

                    var newPosition = originalPointToMove + delta;

                    var    newSize          = (newPosition - bottom).Length;
                    double snapGridDistance = Object3DControlContext.SnapGridDistance;
                    // if we are about to scale the object to less than 0
                    if (up.Dot(info.HitPosition - bottom) < 0)
                    {
                        newSize = .001;
                    }

                    if (snapGridDistance > 0)
                    {
                        newSize = System.Math.Max(newSize, snapGridDistance);
                        // snap this position to the grid
                        newSize = ((int)((newSize / snapGridDistance) + .5)) * snapGridDistance;
                    }

                    scaleController.ScaleHeight(newSize);

                    await selectedItem.Rebuild();

                    var postScaleBottom = GetBottomPosition(selectedItem);

                    selectedItem.Translate(bottom - postScaleBottom);

                    Invalidate();
                }
            }

            base.OnMouseMove(mouseEvent3D, mouseIsOver);
        }
Exemplo n.º 10
0
        public IntersectInfo GetClosestIntersection(Ray ray)
        {
            Ray           localRay           = GetLocalSpaceRay(ray);
            IntersectInfo localIntersection  = child.GetClosestIntersection(localRay);
            IntersectInfo globalIntersection = GetGlobalSpaceInfo(localIntersection);

            return(globalIntersection);
        }
Exemplo n.º 11
0
        private IntersectInfo IntersectSlab(Ray ray, Vector p1, Vector p2, Vector p3)
        {
            var n    = (p1 - p3).CrossProduct(p2 - p3).Normalize();
            var d    = n.DotProduct(p1);
            var info = new IntersectInfo();
            var vd   = n.DotProduct(ray.Direction);

            if (vd == 0)
            {
                return(info); // no intersection
            }

            var t = -(n.DotProduct(ray.Position) - d) / vd;

            if (t <= 0)
            {
                return(info);
            }
            var hit = ray.Position + ray.Direction * t;

            if ((hit.X < p1.X || hit.X > p2.X) && (p1.X != p2.X))
            {
                return(info);
            }
            if ((hit.Y < p3.Y || hit.Y > p1.Y) && (p1.Y != p2.Y))
            {
                return(info);
            }
            //if ((hit.z < P1.z || hit.z > P3.z) && (P1.z != P3.z)) return info;
            if ((hit.Z < p1.Z || hit.Z > p2.Z) && (p1.Z != p2.Z))
            {
                return(info);
            }

            info.Element  = this;
            info.IsHit    = true;
            info.Position = hit;
            info.Normal   = n; // *-1;
            info.Distance = t;

            if (Material.HasTexture)
            {
                //Vector vecU = new Vector(hit.y - Position.y, hit.z - Position.z, Position.x-hit.x);
                var vecU = new Vector((p1.Y + p2.Y) / 2 - Position.Y, (p1.Z + p2.Z) / 2 - Position.Z, Position.X - (p1.X + p2.X) / 2).Normalize();
                var vecV = vecU.CrossProduct((p1 + p2) / 2 - Position).Normalize();

                var u = info.Position.DotProduct(vecU);
                var v = info.Position.DotProduct(vecV);
                info.Color = Material.GetColor(u, v);
            }
            else
            {
                info.Color = Material.GetColor(0, 0);
            }

            return(info);
        }
        public override async void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver)
        {
            var selectedItem = RootSelection;

            activeSelectedItem = selectedItem;
            if (MouseIsOver)
            {
                zValueDisplayInfo.Visible = true;
            }
            else if (!hadClickOnControl)
            {
                zValueDisplayInfo.Visible = false;
            }

            if (MouseDownOnControl)
            {
                IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

                if (info != null &&
                    selectedItem != null)
                {
                    var delta = info.HitPosition - initialHitPosition;

                    var newPosition = originalPointToMove + delta;

                    var lockedBottom = GetBottomPosition(selectedItem);

                    var newSize = (newPosition - lockedBottom).Length;

                    if (Object3DControlContext.SnapGridDistance > 0)
                    {
                        // snap this position to the grid
                        double snapGridDistance = Object3DControlContext.SnapGridDistance;

                        // snap this position to the grid
                        newSize = ((int)((newSize / snapGridDistance) + .5)) * snapGridDistance;
                    }

                    if (selectedItem is IObjectWithHeight heightObject)
                    {
                        heightObject.Height = newSize;
                        selectedItem.Invalidate(new InvalidateArgs(selectedItem, InvalidateType.DisplayValues));
                    }

                    await selectedItem.Rebuild();

                    var postScaleBottom = GetBottomPosition(selectedItem);

                    selectedItem.Translate(lockedBottom - postScaleBottom);

                    Invalidate();
                }
            }

            base.OnMouseMove(mouseEvent3D, mouseIsOver);
        }
Exemplo n.º 13
0
        public IEnumerable IntersectionIterator(Ray ray)
        {
            Ray localRay = GetLocalSpaceRay(ray);

            foreach (IntersectInfo localInfo in Child.IntersectionIterator(localRay))
            {
                IntersectInfo globalIntersection = GetGlobalSpaceInfo(localInfo);
                yield return(globalIntersection);
            }
        }
Exemplo n.º 14
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));
        }
Exemplo n.º 15
0
        private IntersectInfo GetGlobalSpaceInfo(IntersectInfo localInfo)
        {
            if (localInfo == null)
            {
                return(null);
            }
            IntersectInfo globalInfo = new IntersectInfo(localInfo);

            globalInfo.HitPosition = Vector3.TransformPosition(localInfo.HitPosition, this.AxisToWorld);
            globalInfo.normalAtHit = Vector3.TransformVector(localInfo.normalAtHit, this.AxisToWorld);
            return(globalInfo);
        }
Exemplo n.º 16
0
        public override void OnMouseUp(MouseEventArgs mouseEvent)
        {
            base.OnMouseUp(mouseEvent);

            if (mouseEvent.Button != MouseButtons.Left)
            {
                return;
            }

            // Make sure we don't use the trace data before it is ready
            if (mouseDownPosition == mouseEvent.Position &&
                cubeTraceData != null)
            {
                Ray           ray  = world.GetRayForLocalBounds(mouseEvent.Position);
                IntersectInfo info = cubeTraceData.GetClosestIntersection(ray);

                if (info != null)
                {
                    var hitData     = GetHitData(info.HitPosition);
                    var normalAndUp = GetDirectionForFace(hitData);

                    var look = Matrix4X4.LookAt(Vector3.Zero, normalAndUp.normal, normalAndUp.up);

                    var start = new Quaternion(interactionLayer.World.RotationMatrix);
                    var end   = new Quaternion(look);

                    Task.Run(() =>
                    {
                        // TODO: stop any spinning happening in the view
                        double duration = .25;
                        var timer       = Stopwatch.StartNew();
                        var time        = timer.Elapsed.TotalSeconds;

                        while (time < duration)
                        {
                            var current = Quaternion.Slerp(start, end, time / duration);
                            UiThread.RunOnIdle(() =>
                            {
                                interactionLayer.World.RotationMatrix = Matrix4X4.CreateRotation(current);
                                Invalidate();
                            });
                            time = timer.Elapsed.TotalSeconds;
                            Thread.Sleep(10);
                        }

                        interactionLayer.World.RotationMatrix = Matrix4X4.CreateRotation(end);
                        Invalidate();
                    });
                }
            }

            interactionLayer.Focus();
        }
Exemplo n.º 17
0
        public override void OnMouseDown(MouseEvent3DArgs mouseEvent3D)
        {
            zHitHeight    = mouseEvent3D.info.hitPosition.z;
            lastMoveDelta = new Vector3();
            double distanceToHit = Vector3.Dot(mouseEvent3D.info.hitPosition, mouseEvent3D.MouseRay.directionNormal);

            hitPlane = new PlaneShape(mouseEvent3D.MouseRay.directionNormal, distanceToHit, null);

            IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

            zHitHeight = info.hitPosition.z;

            base.OnMouseDown(mouseEvent3D);
        }
Exemplo n.º 18
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);
            }
        }
Exemplo n.º 19
0
        public override void OnMouseMove(Mouse3DEventArgs mouseEvent3D, bool mouseIsOver)
        {
            var selectedItem = RootSelection;

            ActiveSelectedItem = selectedItem;
            if (MouseIsOver)
            {
                zHeightDisplayInfo.Visible = true;
            }
            else if (!hadClickOnControl)
            {
                zHeightDisplayInfo.Visible = false;
            }

            if (MouseDownOnControl)
            {
                IntersectInfo info = hitPlane.GetClosestIntersection(mouseEvent3D.MouseRay);

                if (info != null &&
                    selectedItem != null &&
                    mouseDownSelectedBounds != null)
                {
                    var delta = info.HitPosition.Z - initialHitPosition.Z;

                    double newZPosition = mouseDownSelectedBounds.MinXYZ.Z + delta;

                    if (Object3DControlContext.SnapGridDistance > 0)
                    {
                        // snap this position to the grid
                        double snapGridDistance = Object3DControlContext.SnapGridDistance;

                        // snap this position to the grid
                        newZPosition = ((int)((newZPosition / snapGridDistance) + .5)) * snapGridDistance;
                    }

                    AxisAlignedBoundingBox originalSelectedBounds = selectedItem.GetAxisAlignedBoundingBox();
                    var moveAmount = newZPosition - originalSelectedBounds.MinXYZ.Z;

                    if (moveAmount != 0)
                    {
                        selectedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, moveAmount);
                        Invalidate();
                    }
                }
            }

            base.OnMouseMove(mouseEvent3D, mouseIsOver);
        }
Exemplo n.º 20
0
        public override void OnMouseDown(MouseEventArgs mouseEvent)
        {
            base.OnMouseDown(mouseEvent);

            Vector2 lastMouseMovePoint;

            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.TestIntersection(rayAtPoint, scene);
                    if (info != null)
                    {
                        focusedObject = (BaseShape)info.closestHitObject;
                        if (focusedObject != null && mouseEvent.Clicks == 2)
                        {
                            cameraData.lookAtPoint = focusedObject.GetAxisAlignedBoundingBox().Center;
                            OrientCamera();
                        }
                    }
                }
                needRedraw = true;
                Invalidate();
            }
        }
Exemplo n.º 21
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);
			}
		}
Exemplo n.º 22
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);
        }
Exemplo n.º 23
0
        public ColorF GetColor(IntersectInfo info)
        {
            if (Material.HasTexture)
            {
                Vector3Float normalF = new Vector3Float(Vector3.TransformNormal(face.Normal, worldMatrix));
                Vector3Float vecU    = new Vector3Float(normalF.y, normalF.z, -normalF.x);
                Vector3Float vecV    = Vector3Float.Cross(vecU, normalF);

                double u = Vector3Float.Dot(new Vector3Float(info.HitPosition), vecU);
                double v = Vector3Float.Dot(new Vector3Float(info.HitPosition), vecV);
                return(Material.GetColor(u, v));
            }
            else
            {
                return(Material.GetColor(0, 0));
            }
        }
Exemplo n.º 24
0
        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);
        }
Exemplo n.º 25
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;
		}
Exemplo n.º 26
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            if (SuppressUiVolumes ||
                !this.PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y))
            {
                return;
            }

            Ray           ray  = this.World.GetRayForLocalBounds(mouseEvent.Position);
            IntersectInfo info = null;

            if (MouseDownOnInteractionVolume && volumeIndexWithMouseDown != -1)
            {
                MouseEvent3DArgs mouseEvent3D = new MouseEvent3DArgs(mouseEvent, ray, info);
                interactionVolumes[volumeIndexWithMouseDown].OnMouseMove(mouseEvent3D);
            }
            else
            {
                MouseEvent3DArgs mouseEvent3D = new MouseEvent3DArgs(mouseEvent, ray, info);

                int volumeHitIndex;
                FindInteractionVolumeHit(ray, out volumeHitIndex, out info);

                for (int i = 0; i < interactionVolumes.Count; i++)
                {
                    if (i == volumeHitIndex)
                    {
                        interactionVolumes[i].MouseOver     = true;
                        interactionVolumes[i].MouseMoveInfo = info;

                        HoveredInteractionVolume = interactionVolumes[i];
                    }
                    else
                    {
                        interactionVolumes[i].MouseOver     = false;
                        interactionVolumes[i].MouseMoveInfo = null;
                    }

                    interactionVolumes[i].OnMouseMove(mouseEvent3D);
                }
            }
        }
Exemplo n.º 27
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            if (SuppressUiVolumes ||
                !this.PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y))
            {
                return;
            }

            Ray           ray          = this.World.GetRayForLocalBounds(mouseEvent.Position);
            IntersectInfo info         = null;
            var           mouseEvent3D = new MouseEvent3DArgs(mouseEvent, ray, info);

            if (MouseDownOnInteractionVolume && mouseDownIAVolume != null)
            {
                mouseDownIAVolume.OnMouseMove(mouseEvent3D);
            }
            else
            {
                this.FindInteractionVolumeHit(ray, out InteractionVolume hitIAVolume, out info);

                var iaVolumes = this.InteractionVolumes;

                foreach (var iaVolume in iaVolumes)
                {
                    if (hitIAVolume == iaVolume)
                    {
                        iaVolume.MouseOver       = true;
                        iaVolume.MouseMoveInfo   = info;
                        HoveredInteractionVolume = iaVolume;
                    }
                    else
                    {
                        iaVolume.MouseOver     = false;
                        iaVolume.MouseMoveInfo = null;
                    }

                    // TODO: Why do non-hit volumes get mouse move?
                    iaVolume.OnMouseMove(mouseEvent3D);
                }
            }
        }
Exemplo n.º 28
0
        public override IntersectInfo Intersect(Ray ray)
        {
            var info = new IntersectInfo();
            var vd   = Position.DotProduct(ray.Direction);

            if (vd == 0)
            {
                return(info); // no intersection
            }

            var t = -(Position.DotProduct(ray.Position) + D) / vd;

            if (t <= 0)
            {
                return(info);
            }

            info.Element  = this;
            info.IsHit    = true;
            info.Position = ray.Position + ray.Direction * t;
            info.Normal   = Position; // *-1;
            info.Distance = t;

            if (Material.HasTexture)
            {
                var vecU = new Vector(Position.Y, Position.Z, -Position.X);
                var vecV = vecU.CrossProduct(Position);

                var u = info.Position.DotProduct(vecU);
                var v = info.Position.DotProduct(vecV);
                info.Color = Material.GetColor(u, v);
            }
            else
            {
                info.Color = Material.GetColor(0, 0);
            }

            return(info);
        }
Exemplo n.º 29
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            if (SuppressObject3DControls ||
                !this.PositionWithinLocalBounds(mouseEvent.X, mouseEvent.Y) ||
                !CanSelectObject())
            {
                return;
            }

            Ray           ray          = this.World.GetRayForLocalBounds(mouseEvent.Position);
            IntersectInfo info         = null;
            var           mouseEvent3D = new Mouse3DEventArgs(mouseEvent, ray, info);

            if (MouseDownOnObject3DControlVolume && mouseDownObject3DControl != null)
            {
                mouseDownObject3DControl.OnMouseMove(mouseEvent3D, false);
            }
            else
            {
                this.FindHitObject3DControl(ray, out IObject3DControl hitObject3DControl, out _);

                var object3DControls = this.Object3DControls;

                foreach (var object3DControl in object3DControls)
                {
                    if (hitObject3DControl == object3DControl)
                    {
                        HoveredObject3DControl = object3DControl;
                        object3DControl.OnMouseMove(mouseEvent3D, true);
                    }
                    else
                    {
                        object3DControl.OnMouseMove(mouseEvent3D, false);
                    }
                }
            }
        }
Exemplo n.º 30
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            mouseOver = false;
            // 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), Width, lastMovePosition, movePosition, false);

                if (activeRotationQuaternion != Quaternion.Identity)
                {
                    lastMovePosition = movePosition;
                    object3DControlLayer.World.RotationMatrix = object3DControlLayer.World.RotationMatrix * Matrix4X4.CreateRotation(activeRotationQuaternion);
                    object3DControlLayer.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)
                {
                    mouseOver = true;

                    DrawMouseHover(GetHitData(info.HitPosition));
                }
                else
                {
                    ResetTextures();
                }
            }
        }
Exemplo n.º 31
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            if (trackBallController.CurrentTrackingType != TrackBallController.MouseDownType.None)
            {
                Vector2 lastMouseMovePoint;
                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 info = raytracer.TestIntersection(rayAtPoint, scene);

            if (info != null)
            {
                rayAtPoint.maxDistanceToConsider = double.PositiveInfinity;
                mouseOverColor = raytracer.CalculateColor(rayAtPoint, scene);
            }
        }
Exemplo n.º 32
0
        public override void OnMouseMove(MouseEventArgs mouseEvent)
        {
            base.OnMouseMove(mouseEvent);

            Ray           ray  = trackballTumbleWidget.GetRayFromScreen(mouseEvent.Position);
            IntersectInfo info = null;

            if (MouseDownOnInteractionVolume && volumeIndexWithMouseDown != -1)
            {
                MouseEvent3DArgs mouseEvent3D = new MouseEvent3DArgs(mouseEvent, ray, info);
                interactionVolumes[volumeIndexWithMouseDown].OnMouseMove(mouseEvent3D);
            }
            else
            {
                int volumeHitIndex;
                if (FindInteractionVolumeHit(ray, out volumeHitIndex, out info))
                {
                    if (volumeIndexWithMouseDown == volumeHitIndex)
                    {
                        MouseEvent3DArgs mouseEvent3D = new MouseEvent3DArgs(mouseEvent, ray, info);
                        interactionVolumes[volumeHitIndex].OnMouseMove(mouseEvent3D);
                    }
                }
                for (int i = 0; i < interactionVolumes.Count; i++)
                {
                    if (i == volumeHitIndex)
                    {
                        interactionVolumes[i].MouseOver     = true;
                        interactionVolumes[i].MouseMoveInfo = info;
                    }
                    else
                    {
                        interactionVolumes[i].MouseOver     = false;
                        interactionVolumes[i].MouseMoveInfo = null;
                    }
                }
            }
        }
Exemplo n.º 33
0
		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);
			}
		}
Exemplo n.º 34
0
		public abstract RGBA_Floats GetColor(IntersectInfo info);
Exemplo n.º 35
0
        public RGBA_Floats CreateAndTraceSecondaryRays(IntersectInfo info, Ray ray, Scene scene, int depth)
        {
            // calculate ambient light
            RGBA_Floats infoColorAtHit = info.closestHitObject.GetColor(info);
            RGBA_Floats color = infoColorAtHit * scene.background.Ambience;
            double shininess = Math.Pow(10, info.closestHitObject.Material.Gloss + 1);

            foreach (Light light in scene.lights)
            {

                // calculate diffuse lighting
                Vector3 directiorFromHitToLight = light.Transform.Position - info.hitPosition;
                double distanceToLight = directiorFromHitToLight.Length;
                Vector3 directiorFromHitToLightNormalized = directiorFromHitToLight.GetNormal();

                if (RenderDiffuse)
                {
                    double L = Vector3.Dot(directiorFromHitToLightNormalized, info.normalAtHit);
                    if (L > 0.0f)
                    {
                        color += infoColorAtHit * light.Color * L;
                    }
                }


                // this is the max depth of raytracing.
                // increasing depth will calculate more accurate color, however it will
                // also take longer (exponentially)
                if (depth < 3)
                {
                    // calculate reflection ray
                    if (RenderReflection && info.closestHitObject.Material.Reflection > 0)
                    {
                        Ray reflectionRay = GetReflectionRay(info.hitPosition, info.normalAtHit, ray.direction);
                        IntersectInfo reflectionInfo = TracePrimaryRay(reflectionRay, scene);
                        RGBA_Floats reflectionColorAtHit;// = reflectionInfo.closestHitObject.GetColor(reflectionInfo);
                        if (reflectionInfo.hitType != IntersectionType.None && reflectionInfo.distanceToHit > 0)
                        {
                            // recursive call, this makes reflections expensive
                            reflectionColorAtHit = CreateAndTraceSecondaryRays(reflectionInfo, reflectionRay, scene, depth + 1);
                        }
                        else // does not reflect an object, then reflect background color
                        {
                            reflectionColorAtHit = scene.background.Color;
                        }

                        color = color.Blend(reflectionColorAtHit, info.closestHitObject.Material.Reflection);
                    }

                    //calculate refraction ray
                    if (RenderRefraction && info.closestHitObject.Material.Transparency > 0)
                    {
                        Ray refractionRay = new Ray(info.hitPosition, ray.direction, Ray.sameSurfaceOffset, double.MaxValue);  // GetRefractionRay(info.hitPosition, info.normalAtHit, ray.direction, info.closestHit.Material.Refraction);
                        IntersectInfo refractionInfo = TracePrimaryRay(refractionRay, scene);
                        RGBA_Floats refractionColorAtHit = refractionInfo.closestHitObject.GetColor(refractionInfo);
                        if (refractionInfo.hitType != IntersectionType.None && refractionInfo.distanceToHit > 0)
                        {
                            // recursive call, this makes refractions expensive
                            refractionColorAtHit = CreateAndTraceSecondaryRays(refractionInfo, refractionRay, scene, depth + 1);
                        }
                        else
                        {
                            refractionColorAtHit = scene.background.Color;
                        }

                        color = refractionColorAtHit.Blend(color, info.closestHitObject.Material.Transparency);
                    }
                }


                IntersectInfo shadow = new IntersectInfo();
                if (RenderShadow)
                {
                    // calculate shadow, create ray from intersection point to light
                    Ray shadowRay = new Ray(info.hitPosition, directiorFromHitToLightNormalized, Ray.sameSurfaceOffset, double.MaxValue); // it may be usefull to limit the legth to te dist to the camera (but I doubt it LBB).
                    shadowRay.isShadowRay = true;

                    // if the normal at the closest hit is away from the shadow it is already it it's own shadow.
                    if (Vector3.Dot(info.normalAtHit, directiorFromHitToLightNormalized) < 0)
                    {
                        shadow.hitType = IntersectionType.FrontFace;
                        color *= 0.5;// +0.5 * Math.Pow(shadow.closestHit.Material.Transparency, 0.5); // Math.Pow(.5, shadow.HitCount);
                    }
                    else
                    {
                        // find any element in between intersection point and light
                        shadow = TracePrimaryRay(shadowRay, scene);
                        if (shadow.hitType != IntersectionType.None && shadow.closestHitObject != info.closestHitObject && shadow.distanceToHit < distanceToLight)
                        {
                            // only cast shadow if the found interesection is another
                            // element than the current element
                            color *= 0.5;// +0.5 * Math.Pow(shadow.closestHit.Material.Transparency, 0.5); // Math.Pow(.5, shadow.HitCount);
                        }
                    }
                }

                // only show highlights if it is not in the shadow of another object
                if (RenderHighlights && shadow.hitType == IntersectionType.None && info.closestHitObject.Material.Gloss > 0)
                {
                    // only show Gloss light if it is not in a shadow of another element.
                    // calculate Gloss lighting (Phong)
                    Vector3 Lv = (info.hitPosition - light.Transform.Position).GetNormal();
                    Vector3 E = (scene.camera.Origin - info.hitPosition).GetNormal();
                    Vector3 H = (E - Lv).GetNormal();

                    double Glossweight = 0.0;
                    Glossweight = Math.Pow(Math.Max(Vector3.Dot(info.normalAtHit, H), 0), shininess);
                    color += light.Color * (Glossweight);
                }
            }

            color.Clamp0To1();
            return color;
        }
Exemplo n.º 36
0
        public void TracePrimaryRayBundle(RayBundle rayBundle, IntersectInfo[] intersectionsForBundle, Scene scene)
        {
            if (scene.shapes.Count != 1)
            {
                throw new Exception("You can only trace a ray bundle into a sigle shape, usually a BoundingVolumeHierachy.");
            }

            scene.shapes[0].GetClosestIntersections(rayBundle, 0, intersectionsForBundle);
        }
Exemplo n.º 37
0
		public void GetClosestIntersections(RayBundle rayBundle, int rayIndexToStartCheckingFrom, IntersectInfo[] intersectionsForBundle)
		{
			intersectionsForBundle[rayIndexToStartCheckingFrom] = GetClosestIntersection(rayBundle.rayArray[rayIndexToStartCheckingFrom]);
		}
Exemplo n.º 38
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);
		}
Exemplo n.º 39
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;
                        }
                    }
                }
            }
        }
Exemplo n.º 40
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;
		}
Exemplo n.º 41
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);
     }
 }
Exemplo n.º 42
0
 public void GetClosestIntersections(RayBundle rayBundle, int rayIndexToStartCheckingFrom, IntersectInfo[] intersectionsForBundle)
 {
     for (int i = 0; i < rayBundle.rayArray.Length; i++)
     {
         rayBundle.rayArray[i] = GetLocalSpaceRay(rayBundle.rayArray[i]);
     }
     child.GetClosestIntersections(rayBundle, rayIndexToStartCheckingFrom, intersectionsForBundle);
     for (int i = 0; i < rayBundle.rayArray.Length; i++)
     {
         intersectionsForBundle[i] = GetGlobalSpaceInfo(intersectionsForBundle[i]);
     }
 }
Exemplo n.º 43
0
 private IntersectInfo GetGlobalSpaceInfo(IntersectInfo localInfo)
 {
     if (localInfo == null)
     {
         return null;
     }
     IntersectInfo globalInfo = new IntersectInfo(localInfo);
     globalInfo.hitPosition = Vector3.TransformPosition(localInfo.hitPosition, this.AxisToWorld);
     globalInfo.normalAtHit = Vector3.TransformVector(localInfo.normalAtHit, this.AxisToWorld);
     return globalInfo;
 }
Exemplo n.º 44
0
		public void GetClosestIntersections(RayBundle rayBundle, int rayIndexToStartCheckingFrom, IntersectInfo[] intersectionsForBundle)
		{
			throw new NotImplementedException();
		}
Exemplo n.º 45
0
		public RGBA_Floats GetColor(IntersectInfo info)
		{
			throw new NotImplementedException("You should not get a color directly from a Difference.");
		}
Exemplo n.º 46
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;
        }
Exemplo n.º 47
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;
				}
			}
		}
Exemplo n.º 48
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;
		}
Exemplo n.º 49
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;
		}
Exemplo n.º 50
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;
				}
			}
		}
Exemplo n.º 51
0
		public virtual void GetClosestIntersections(RayBundle rayBundle, int rayIndexToStartCheckingFrom, IntersectInfo[] intersectionsForBundle)
		{
			throw new NotImplementedException("Implement this for the class you want.");
		}
Exemplo n.º 52
0
 public RGBA_Floats GetColor(IntersectInfo info)
 {
     return child.GetColor(info);
 }
Exemplo n.º 53
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;
		}
Exemplo n.º 54
0
		public RGBA_Floats GetColor(IntersectInfo info)
		{
			throw new NotImplementedException("You should not get a color directly from a BoundingVolumeHierarchy.");
		}
Exemplo n.º 55
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);
			}
		}
Exemplo n.º 56
0
		public void GetClosestIntersections(RayBundle rayBundle, int rayIndexToStartCheckingFrom, IntersectInfo[] intersectionsForBundle)
		{
			int startRayIndex = FindFirstRay(rayBundle, rayIndexToStartCheckingFrom);
			if (startRayIndex != -1)
			{
				IPrimitive checkFirst = nodeA;
				IPrimitive checkSecond = nodeB;
				if (rayBundle.rayArray[startRayIndex].directionNormal[splitingPlane] < 0)
				{
					checkFirst = nodeB;
					checkSecond = nodeA;
				}

				checkFirst.GetClosestIntersections(rayBundle, startRayIndex, intersectionsForBundle);
				if (checkSecond != null)
				{
					checkSecond.GetClosestIntersections(rayBundle, startRayIndex, intersectionsForBundle);
				}
			}
		}
Exemplo n.º 57
0
        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;
		}
Exemplo n.º 58
0
		public override void OnMouseDown(MouseEventArgs mouseEvent)
		{
			// Show transform override
			if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Right)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Rotate;
			}
			else if (activeButtonBeforeMouseOverride == null && mouseEvent.Button == MouseButtons.Middle)
			{
				activeButtonBeforeMouseOverride = viewControls3D.ActiveButton;
				viewControls3D.ActiveButton = ViewControls3DButtons.Translate;
			}

			autoRotating = false;
			base.OnMouseDown(mouseEvent);
			if (meshViewerWidget.TrackballTumbleWidget.UnderMouseState == Agg.UI.UnderMouseState.FirstUnderMouse)
			{
				if (meshViewerWidget.TrackballTumbleWidget.TransformState == TrackBallController.MouseDownType.None
					&& mouseEvent.Button == MouseButtons.Left
					&& ModifierKeys != Keys.Shift
					&& ModifierKeys != Keys.Control
					&& ModifierKeys != Keys.Alt)
				{
					if (!meshViewerWidget.MouseDownOnInteractionVolume)
					{
						int meshGroupHitIndex;
						IntersectInfo info = new IntersectInfo();
						if (FindMeshGroupHitPosition(mouseEvent.Position, out meshGroupHitIndex, ref info))
						{
							CurrentSelectInfo.HitPlane = new PlaneShape(Vector3.UnitZ, CurrentSelectInfo.PlaneDownHitPos.z, null);
							SelectedMeshGroupIndex = meshGroupHitIndex;

							transformOnMouseDown = SelectedMeshGroupTransform;

							Invalidate();
							CurrentSelectInfo.DownOnPart = true;

							AxisAlignedBoundingBox selectedBounds = meshViewerWidget.GetBoundsForSelection();

							if (info.hitPosition.x < selectedBounds.Center.x)
							{
								if (info.hitPosition.y < selectedBounds.Center.y)
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.LB;
								}
								else
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.LT;
								}
							}
							else
							{
								if (info.hitPosition.y < selectedBounds.Center.y)
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.RB;
								}
								else
								{
									CurrentSelectInfo.HitQuadrant = HitQuadrant.RT;
								}
							}
						}
						else
						{
							SelectedMeshGroupIndex = -1;
						}

						SelectedTransformChanged?.Invoke(this, null);
					}
				}
			}
		}
Exemplo n.º 59
0
        public IntersectInfo TracePrimaryRay(Ray ray, Scene scene)
        {
            IntersectInfo primaryRayIntersection = new IntersectInfo();

            foreach (IRayTraceable 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;
        }
Exemplo n.º 60
0
		public MouseEvent3DArgs(MouseEventArgs mouseEvent2D, Ray mouseRay, IntersectInfo info)
		{
			this.info = info;
			this.MouseEvent2D = mouseEvent2D;
			this.mouseRay = mouseRay;
		}