// todo: implement mouse-in / mouse-out interaction events instead
        public override void OnRoutedEvent(IRoutedEvent evnt)
        {
            if (!(evnt is IMouseEvent mevent))
            {
                return;
            }
            var layer = mevent.Viewport.View.Layers.FirstOrDefault(x => x.VisibleScene == Node.Scene);

            if (layer == null)
            {
                return;
            }
            var rayHitInfo  = new RayCastInfo(mevent.Viewport, layer, mevent.State.Position);
            var isMouseOver = Node.SearchComponents <IRayHittableComponent>()
                              .Any(x => x.HitWithClick(rayHitInfo).Successful);

            if (!wasMouseOver && isMouseOver)
            {
                highlightOnMouseService.OnObjectIn(this, GroupName);
            }
            else if (wasMouseOver && !isMouseOver)
            {
                highlightOnMouseService.OnObjectOut(this, GroupName);
            }
            wasMouseOver = isMouseOver;
        }
Esempio n. 2
0
 public void Init(BoxCollider2D collider2D)
 {
     col    = collider2D;
     points = new RayCastPoint( );
     info   = new RayCastInfo( );
     result = new List <HitResult> ( );
     CalculateSpace( );
 }
Esempio n. 3
0
        public RayHitResult HitWithClick(RayCastInfo clickInfo)
        {
            var globalRay     = clickInfo.GlobalRay;
            var sphere        = getSphere(master);
            var segmentLength = (sphere.Center - globalRay.Point).Length() * 3;
            var segment       = new LineSegment3(globalRay.Point, globalRay.Point + globalRay.Direction * segmentLength);

            sphere.Intersect(segment, out var p1, out var p2);

            if (!p1.HasValue)
            {
                return(RayHitResult.Failure());
            }
            var d1 = (p1.Value - globalRay.Point).Length();

            Vector3 globalPoint;
            float   distance;

            if (p2.HasValue)
            {
                var d2   = (p2.Value - globalRay.Point).Length();
                var use1 = (d1 <= d2) ^ inverted;
                if (use1)
                {
                    globalPoint = p1.Value;
                    distance    = d1;
                }
                else
                {
                    globalPoint = p2.Value;
                    distance    = d2;
                }
            }
            else
            {
                globalPoint = p1.Value;
                distance    = d1;
            }

            // todo: consider rotation
            var localPoint = (globalPoint - sphere.Center) / sphere.Radius;

            return(new RayHitResult
            {
                Successful = true,
                Node = Node,
                Distance = distance,
                GlobalHitPoint = globalPoint,
                LocalHitPoint = localPoint,
                IntTag = intTag,
                StrTag = strTag
            });
        }
        public RayHitResult HitWithClick(RayCastInfo clickInfo)
        {
            var hitResult = hittable.HitWithClick(clickInfo);
            var cRect     = GetRectComponent();

            // todo: make overridable and override in more specific components
            if (cRect.DragByBorders &&
                (1 - hitResult.LocalHitPoint.X.Abs()) * cRect.Rectangle.HalfWidth * RichTextBox.DefaultPixelScaling > RichTextBox.DraggablePaddingInPixels &&
                (1 - hitResult.LocalHitPoint.Y.Abs()) * cRect.Rectangle.HalfHeight * RichTextBox.DefaultPixelScaling > RichTextBox.DraggablePaddingInPixels)
            {
                return(RayHitResult.Failure());
            }
            return(hitResult);
        }
    void DrawRaycast()
    {
        int   rayCount     = meshResolution;
        float rayAngleSize = lightAngle / (rayCount);

        List <Vector3> rayPoints = new List <Vector3>();

        for (int i = 0; i <= rayCount; i++)
        {
            float angle = transform.eulerAngles.z - lightAngle / 2 + rayAngleSize * i;
            Debug.DrawLine(transform.position, transform.position + DirFromAngle(angle, true) * lightRadius, Color.red);
            RayCastInfo newRayCastInfo = RayCasting(angle);
            rayPoints.Add(newRayCastInfo.point);
        }


        int vertexCount = rayPoints.Count + 1;

        Vector3[] vertices  = new Vector3[vertexCount + 1];
        int[]     triangles = new int[(vertexCount - 2) * 3];

        print("vertex count " + vertexCount);
        print("ray point " + rayPoints.Count);
        print("vertices count" + vertices.Length);

        vertices[0] = Vector3.zero;
        for (int i = 0; i < vertexCount - 1; i++)
        {
            vertices[i + 1] = transform.InverseTransformPoint(rayPoints[i]);

            if (i < vertexCount - 2)
            {
                triangles[i * 3]     = 0;
                triangles[i * 3 + 1] = i + 1;
                triangles[i * 3 + 2] = i + 2;
            }
        }

        viewMesh.Clear();

        viewMesh.vertices  = vertices;
        viewMesh.triangles = triangles;
        viewMesh.RecalculateNormals();
    }
Esempio n. 6
0
    /*
     * ============================================================================
     * FindEdge()
     *  Iteratively looks for the edge of an obstacle. THe higher the
     *  edgeIterations, the more refined we can make that edge. Takes two
     *  RayCastInfo parameters as the minimum and maximum of the ray cast.
     *  The function works by egetting the two ray casts where one is a hit and
     *  the other is a miss, creating a new ray cast down the middle and then
     *  repeating between a higt and a missd cast until the threshold or
     *  iterations limit is reached.
     * ============================================================================
     */
    private EdgeInfo FindEdge(RayCastInfo minRayCast, RayCastInfo maxRayCast)
    {
        float   minAngle = minRayCast.angle;
        float   maxAngle = maxRayCast.angle;
        Vector3 minPoint = Vector3.zero;
        Vector3 maxPoint = Vector3.zero;

        RayCastInfo newRayCast = new RayCastInfo();

        for (int i = 0; i < edgeIterations; i++)
        {
            float angle = (minAngle + maxAngle) / 2;
            newRayCast = RayCast(angle);
            bool edgeDistThresholExeeded = Mathf.Abs(minRayCast.dist - newRayCast.dist) > edgeDistThreshold;
            if (newRayCast.hit == minRayCast.hit && !edgeDistThresholExeeded)
            {
                // Replace the minimum with the new ray cast we have created
                minAngle = angle;
                minPoint = newRayCast.point;
            }
            else
            {
                // Replace the max as the new ray ast we have created
                maxAngle = angle;
                maxPoint = newRayCast.point;
            }
        }

        Debug.DrawLine(transform.position, minPoint, Color.blue);
        Debug.DrawLine(transform.position, maxPoint, Color.blue);

        if (newRayCast.hit && Mathf.Round(newRayCast.dist) < MaxRange)
        {
            EdgePoints.Add(minPoint);
        }
        else if (!newRayCast.hit && Mathf.Round(newRayCast.dist) < MaxRange)
        {
            EdgePoints.Add(maxPoint);
        }
        return(new EdgeInfo(minPoint, maxPoint));
    }
Esempio n. 7
0
        public RayHitResult HitWithClick(RayCastInfo clickInfo)
        {
            var globalRay = clickInfo.GlobalRay;
            var globalTransformInverse = (planeTransform * Node.GlobalTransform).Invert();
            var localRay = globalRay * globalTransformInverse;

            var t = -localRay.Point.Z / localRay.Direction.Z;

            if (t <= 0f)
            {
                return(RayHitResult.Failure());
            }

            var point     = localRay.Point + localRay.Direction * t;
            var rectangle = getLocalRectangle(master);

            if (!rectangle.ContainsPoint(point.Xy))
            {
                return(RayHitResult.Failure());
            }

            var globalT     = t / globalTransformInverse.Scale;
            var offset      = getHitDistanceOffset(master);
            var globalPoint = globalRay.Point + globalRay.Direction * globalT;
            var localPoint  = new Vector3(
                (point.X - rectangle.Center.X) / rectangle.HalfWidth,
                (point.Y - rectangle.Center.Y) / rectangle.HalfHeight,
                0);

            return(new RayHitResult
            {
                Successful = true,
                Node = Node,
                Distance = globalT + offset,
                GlobalHitPoint = globalPoint,
                LocalHitPoint = localPoint,
                IntTag = intTag,
                StrTag = strTag
            });
        }
Esempio n. 8
0
        public bool TryHandleInputEvent(IInputEvent eventArgs)
        {
            if (!(eventArgs is MouseEvent args))
            {
                return(false);
            }
            if (!args.IsLeftClickEvent())
            {
                return(false);
            }
            var clickInfo = new RayCastInfo(args.Viewport, args.Viewport.View.Layers.Single(), args.State.Position);
            var hitResult = rayHitIndex.CastRay(clickInfo).FirstOrNull() ?? RayHitResult.Failure();

            if (hitResult.Successful)
            {
                int?to = null;
                var gizmoComponentTo = hitResult.Node.GetComponent <StoryFlowchartNodeGizmoComponent>();
                if (gizmoComponentTo != null && gizmoComponentTo.ReferencedNode.Id != from)
                {
                    to = gizmoComponentTo.ReferencedNode.Id;
                }

                if (storyService.GlobalGraph.NodeIds.Contains(hitResult.Node.Id))
                {
                    to = hitResult.Node.Id;
                }

                if (to.HasValue)
                {
                    var child = StoryOperations.AddChild(storyService, commonNodeFactory, to.Value, this);
                    storyService.AddEdge(from, child.Id);
                    toolService.CurrentTool = null;
                    return(true);
                }
            }
            toolService.CurrentTool = null;
            return(false);
        }
Esempio n. 9
0
        public RayHitResult HitWithClick(RayCastInfo clickInfo)
        {
            var globalRay = clickInfo.GlobalRay;
            var globalTransformInverse = (planeTransform * Node.GlobalTransform).Invert();
            var localRay = globalRay * globalTransformInverse;

            var t = -localRay.Point.Z / localRay.Direction.Z;

            if (t <= 0f)
            {
                return(RayHitResult.Failure());
            }

            var point  = localRay.Point + localRay.Direction * t;
            var cirlce = getLocalCirlce(master);

            if (!cirlce.Contains(point.Xy))
            {
                return(RayHitResult.Failure());
            }

            var globalT     = t / globalTransformInverse.Scale;
            var offset      = getHitDistanceOffset(master);
            var globalPoint = globalRay.Point + globalRay.Direction * globalT;
            // todo: consider rotation
            var localPoint = new Vector3(point.Xy - cirlce.Center, 0) / cirlce.Radius;

            return(new RayHitResult
            {
                Successful = true,
                Node = Node,
                Distance = globalT + offset,
                GlobalHitPoint = globalPoint,
                LocalHitPoint = localPoint,
                IntTag = intTag,
                StrTag = strTag
            });
        }
Esempio n. 10
0
        public RayHitResult HitWithClick(RayCastInfo clickInfo)
        {
            // todo: calculate in screen space?
            var line      = getLine(master);
            var mouseLine = clickInfo.GlobalRay.ToLine();

            Line3.GetClosestPoints(line, mouseLine, out var p1, out var p2);
            var grad      = clickInfo.GetAbsPixelGradientAt((p1 + p2) / 2);
            var diff      = (p2 - p1).Abs();
            var pixelDiff = Vector3.Dot(diff, grad);

            return(pixelDiff <= lineWidth
                ? new RayHitResult
            {
                Successful = true,
                Node = Node,
                Distance = (clickInfo.GlobalRay.Point - p1).Length(),
                GlobalHitPoint = p1,
                LocalHitPoint = p1,
                IntTag = intTag,
                StrTag = strTag
            }
                : RayHitResult.Failure());
        }
 // Hittable
 public RayHitResult HitWithClick(RayCastInfo clickInfo) => hittable.HitWithClick(clickInfo);
Esempio n. 12
0
 public RayHitResult HitWithClick(RayCastInfo clickInfo) =>
 RayHitResult.Failure();
Esempio n. 13
0
 // Hittable
 public RayHitResult HitWithClick(RayCastInfo clickInfo) => hittable?.HitWithClick(clickInfo) ?? RayHitResult.Failure();
Esempio n. 14
0
    /*
     * ================================
     * DrawRange()
     *  This is the main function for the LIDAR where the LOS circle is drawn
     *  and it calls the other functions to ascertain the raycasts.
     * ================================
     */
    void DrawRange()
    {
        EdgePoints.Clear();
        int            stepCount     = Mathf.RoundToInt(ScanAngle * (1.0f / ScanResolution));
        float          stepAngleSize = ScanAngle / stepCount;
        List <Vector3> scanPoints    = new List <Vector3>();
        RayCastInfo    oldRayCast    = new RayCastInfo();

        for (int i = 0; i <= stepCount; i++)
        {
            float angle = transform.eulerAngles.y - ScanAngle / 2
                          + stepAngleSize * i;
            RayCastInfo newRayCast = RayCast(angle);
            if (i > 0)
            {
                bool edgeDistThresholExeeded =
                    Mathf.Abs(oldRayCast.dist - newRayCast.dist)
                    > edgeDistThreshold;
                if (oldRayCast.hit != newRayCast.hit || (oldRayCast.hit && newRayCast.hit && edgeDistThresholExeeded))
                {
                    // Find the edgeb etween the two raycasts
                    EdgeInfo edge = FindEdge(oldRayCast, newRayCast);
                    if (edge.pointA != Vector3.zero)
                    {
                        scanPoints.Add(edge.pointA);
                        if (Mathf.Round(Vector3.Distance(transform.position, edge.pointA)) < MaxRange)
                        {
                            EdgePoints.Add(edge.pointA);
                        }
                    }
                    if (edge.pointB != Vector3.zero)
                    {
                        scanPoints.Add(edge.pointB);
                        if (Mathf.Round(Vector3.Distance(transform.position, edge.pointB)) < MaxRange)
                        {
                            EdgePoints.Add(edge.pointB);
                        }
                    }
                }
            }
        } // End for

        // Start setting up the mesh
        int vCount = scanPoints.Count + 1;               // How many vertices? Points + origin

        Vector3[] vertices  = new Vector3[vCount];       // Create vertices array from the prev. calc
        int[]     triangles = new int[(vCount - 2) * 3]; // Triangles have 3 points each

        vertices[0] = Vector3.zero;                      // Set origin as 0
        for (int i = 0; i < vCount - 1; i++)
        {
            vertices[i + 1] = transform.InverseTransformPoint(scanPoints[i]) + Vector3.forward;

            if (i < vCount - 2)
            {
                triangles[i * 3]     = 0;               // Firstr triangle point is origin
                triangles[i * 3 + 1] = i + 1;           // goes clockwise
                triangles[i * 3 + 2] = i + 2;           // ...
            }
        }

        // Draw the mesh
        ScanMesh.Clear();
        ScanMesh.vertices  = vertices;
        ScanMesh.triangles = triangles;
        ScanMesh.RecalculateNormals();
    }
 public RayHitResult HitWithClick(RayCastInfo clickInfo)
 {
     return(hittable.HitWithClick(clickInfo));
 }
Esempio n. 16
0
        private void OnEvent(IInteractionEvent interactionEvent)
        {
            if (!(interactionEvent is IInputEvent inputEvent))
            {
                return;
            }
            locksToRelease.Clear();
            foreach (var inputLock in inputLocks)
            {
                var result = inputLock.ProcessEvent(inputEvent);
                if ((result & InputEventProcessResult.StopPropagating) != 0)
                {
                    return;
                }
                if ((result & InputEventProcessResult.ReleaseLock) != 0)
                {
                    locksToRelease.Add(inputLock);
                }
            }
            foreach (var inputLock in locksToRelease)
            {
                inputLocks.Remove(inputLock);
            }

            if (toolService.CurrentTool != null)
            {
                var tool = toolService.CurrentTool;
                if (tool.TryHandleInputEvent(inputEvent))
                {
                    return;
                }
            }

            if (dirtyHackServiceLazy.Value.TryHandleInput(inputEvent))
            {
                return;
            }

            //if (abstractArgs is IMouseEventArgs mouseArgs)
            //    OnMouseEvent(mouseArgs);
            //else if (abstractArgs is IKeyEventArgs keyboardArgs)
            //    OnKeyEvent(keyboardArgs);
            // todo: return if handled

            if (inputEvent.Viewport?.View.TryHandleInput(inputEvent) ?? false)
            {
                return;
            }

            if (inputEvent.Viewport != null && inputEvent is IMouseEvent margs)
            {
                var hitSomething = false;
                foreach (var layer in inputEvent.Viewport.View.Layers)
                {
                    var clickInfo  = new RayCastInfo(margs.Viewport, layer, margs.State.Position);
                    var hitResults = rayHitIndex.CastRay(clickInfo);
                    // todo: introduce different levels of stopping propagation and remove '.Take(1)'
                    foreach (var hitResult in hitResults.Take(1))
                    {
                        hitSomething       = true;
                        margs.RayHitResult = hitResult;
                        foreach (var interactionElement in hitResult.Node.SearchComponents <IInteractionComponent>())
                        {
                            if (interactionElement.TryHandleInteractionEvent(margs))
                            {
                                return;
                            }
                        }
                    }
                    margs.RayHitResult = null;
                    if (layer.Camera is IControlledCamera controlledCamera && controlledCamera.TryHandleInput(inputEvent))
                    {
                        return;
                    }
                }
                if (margs.IsLeftClickEvent() && margs.KeyModifiers == KeyModifiers.None && !hitSomething)
                {
                    viewService.SelectedNode = null;
                }
            }

            if (inputEvent is IKeyEvent kargs && viewService.SelectedNode != null)
            {
                foreach (var interactionElement in viewService.SelectedNode.Node.SearchComponents <IInteractionComponent>())
                {
                    if (interactionElement.TryHandleInteractionEvent(kargs))
                    {
                        return;
                    }
                }
            }

            navigationService.TryHandleInput(inputEvent);
        }