private void HandleSceneViewSelectTool(Event current, SceneView sceneView)
        {
            // TODO: Add keys to select body, shape etc.

            // Routes each selected object to its correct selection.
            // Assigning 'selectedObjects' to 'Selection.objects' doesn't
            // trigger onSelectionChanged (desired behavior).
            UnityEngine.Object[] selectedObjects = Selection.objects;
            bool selectRigidBodyMode             = SelectRigidBodyTrigger(current, sceneView);
            bool hasChanges = false;

            for (int i = 0; i < selectedObjects.Length; ++i)
            {
                if (selectedObjects[i] == null)
                {
                    continue;
                }

                // TODO: Key combo to select bodies etc.
                UnityEngine.Object routedObject = Manager.RouteObject(selectedObjects[i]);
                AGXUnity.RigidBody rigidBody    = selectRigidBodyMode &&
                                                  routedObject != null &&
                                                  routedObject is GameObject ?
                                                  (routedObject as GameObject).GetComponentInParent <AGXUnity.RigidBody>() :
                                                  null;
                selectedObjects[i] = rigidBody != null ? rigidBody.gameObject : routedObject;
                hasChanges         = true;
            }
            if (hasChanges)
            {
                Selection.objects = selectedObjects;
            }

            if (SelectGameObjectTrigger(current, sceneView))
            {
                // User is holding activate select tool - SelectGameObjectTool is waiting for the mouse click.
                if (SelectGameObject == null)
                {
                    SelectGameObject = new SelectGameObjectTool()
                    {
                        OnSelect = go => { Selection.activeGameObject = go; }
                    }
                }
                ;
            }
            // The user has released select game object trigger and the window isn't showing.
            else if (SelectGameObject != null && !SelectGameObject.SelectionWindowActive)
            {
                SelectGameObject = null;
            }
        }
Beispiel #2
0
        public override void OnSceneViewGUI(SceneView sceneView)
        {
            if (m_collectedData == null)
            {
                if (GetChild <SelectGameObjectTool>() == null)
                {
                    SelectGameObjectTool selectGameObjectTool = new SelectGameObjectTool();
                    selectGameObjectTool.OnSelect = go =>
                    {
                        m_collectedData = new CollectedData()
                        {
                            Target = go
                        };
                    };
                    AddChild(selectGameObjectTool);
                }
            }
            else if (!m_collectedData.TriangleGiven)
            {
                // TODO: Handle world point?
                if (m_collectedData.Target == null)
                {
                    PerformRemoveFromParent();
                    return;
                }

                HighlightObject = m_collectedData.Target;

                m_collectedData.RaycastResult = Utils.Raycast.Intersect(HandleUtility.GUIPointToWorldRay(Event.current.mousePosition),
                                                                        m_collectedData.Target,
                                                                        m_collectedData.Target.GetComponent <AGXUnity.RigidBody>() != null);

                // Done (next state) when the user left click and we've a valid triangle.
                m_collectedData.TriangleGiven = m_collectedData.RaycastResult && Manager.HijackLeftMouseClick();
            }
            else if (!m_collectedData.RotationGiven)
            {
                if (GetChild <DirectionTool>() == null)
                {
                    DirectionTool directionTool = new DirectionTool(m_collectedData.RaycastResult.Point,
                                                                    m_collectedData.RaycastResult.Triangle.Normal,
                                                                    m_collectedData.RaycastResult.ClosestEdge.Direction);

                    directionTool.OnSelect += (position, rotation) =>
                    {
                        m_collectedData.Rotation      = rotation;
                        m_collectedData.RotationGiven = true;
                    };

                    AddChild(directionTool);
                }
            }
            else
            {
                Result resultingData = new Result()
                {
                    Target        = m_collectedData.Target,
                    RaycastResult = m_collectedData.RaycastResult,
                    Rotation      = m_collectedData.Rotation
                };

                OnPointFound(resultingData);
                PerformRemoveFromParent();
            }

            PointVisual.Visible = m_collectedData != null && m_collectedData.RaycastResult && !m_collectedData.TriangleGiven;
            if (PointVisual.Visible)
            {
                PointVisual.SetTransform(m_collectedData.RaycastResult.Point, Quaternion.identity, 0.05f);
            }
        }
Beispiel #3
0
        public override void OnSceneViewGUI(SceneView sceneView)
        {
            if (EdgeVisual.Visible && EdgeVisual.MouseOver)
            {
                return;
            }

            // 1. Find target game object.
            if (m_collectedData == null)
            {
                if (GetChild <SelectGameObjectTool>() == null)
                {
                    SelectGameObjectTool selectGameObjectTool = new SelectGameObjectTool();
                    selectGameObjectTool.OnSelect = go =>
                    {
                        m_collectedData = new CollectedData()
                        {
                            Target = go
                        };
                    };
                    AddChild(selectGameObjectTool);
                }
            }
            // 2. Select edge on target game object.
            else if (!m_collectedData.SelectedEdge.Valid)
            {
                HighlightObject = m_collectedData.Target;

                // Similar behavior as FindPointTool - remove ourself if
                // the users choice is World.
                if (m_collectedData.Target == null)
                {
                    PerformRemoveFromParent();
                    return;
                }
                var ray    = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                var result = Utils.Raycast.Intersect(ray,
                                                     m_collectedData.Target);

                m_collectedData.CurrentEdge = FindClosestEdgeIncludingTargetPrincipalAxes(ray, result.ClosestEdge);
            }
            // 3. Find point on edge - hold ctrl for "no-snap" mode.
            else if (!m_collectedData.PointOnEdgeGiven)
            {
                Vector3 pointOnEdge = FindClosestPointOnEdge(m_collectedData.SelectedEdge);

                if (Event.current.control)
                {
                    m_collectedData.PointOnEdge = pointOnEdge;
                }
                else
                {
                    float     snapValue        = 0.5f * HandleUtility.GetHandleSize(pointOnEdge);
                    float     closestDistance  = float.PositiveInfinity;
                    Vector3   closestPoint     = pointOnEdge;
                    Vector3[] predefinedPoints = FindPredefinedEdgePoints(m_collectedData.SelectedEdge).ToArray();
                    // Given set of predefined points along the edge, finds the
                    // closest to the mouse ray (i.e., the actual point on the edge).
                    foreach (var point in predefinedPoints)
                    {
                        float distanceToPoint = Vector3.Distance(pointOnEdge, point);
                        if (distanceToPoint < snapValue && distanceToPoint < closestDistance)
                        {
                            closestPoint    = point;
                            closestDistance = distanceToPoint;
                        }
                    }

                    m_collectedData.PointOnEdge = closestPoint;
                }
            }
            // 4. Find direction.
            else if (!m_collectedData.DirectionGiven)
            {
                if (GetChild <DirectionTool>() == null)
                {
                    DirectionTool directionTool = new DirectionTool(m_collectedData.PointOnEdge,
                                                                    m_collectedData.SelectedEdge.Direction,
                                                                    m_collectedData.SelectedEdge.Normal);
                    directionTool.OnSelect += (position, rotation) =>
                    {
                        m_collectedData.DirectionRotation = rotation;
                        m_collectedData.DirectionGiven    = true;
                    };
                    AddChild(directionTool);
                }
            }
            // 5. Done, fire callback with result and remove us.
            else
            {
                var orgEdge       = m_collectedData.SelectedEdge;
                var resultingData = new Result()
                {
                    Target = m_collectedData.Target,
                    Edge   = new AGXUnity.Edge()
                    {
                        Start  = m_collectedData.PointOnEdge + 0.5f * orgEdge.Length * (m_collectedData.DirectionRotation * Vector3.back),
                        End    = m_collectedData.PointOnEdge + 0.5f * orgEdge.Length * (m_collectedData.DirectionRotation * Vector3.forward),
                        Normal = m_collectedData.DirectionRotation * Vector3.up,
                        Type   = AGXUnity.Edge.EdgeType.Triangle
                    },
                    Position = m_collectedData.PointOnEdge,
                    Rotation = m_collectedData.DirectionRotation
                };

                OnEdgeFound(resultingData);

                PerformRemoveFromParent();

                return;
            }

            EdgeVisual.Visible = m_collectedData != null && m_collectedData.CurrentEdge.Valid;
            if (EdgeVisual.Visible)
            {
                const float edgeRadius     = 0.035f;
                const float defaultAlpha   = 0.25f;
                const float mouseOverAlpha = 0.65f;

                EdgeVisual.SetTransform(m_collectedData.CurrentEdge.Start, m_collectedData.CurrentEdge.End, edgeRadius);

                if (m_collectedData.CurrentEdge.Type == AGXUnity.Edge.EdgeType.Triangle)
                {
                    EdgeVisual.Color          = new Color(Color.yellow.r, Color.yellow.g, Color.yellow.b, defaultAlpha);
                    EdgeVisual.MouseOverColor = new Color(Color.yellow.r, Color.yellow.g, Color.yellow.b, mouseOverAlpha);
                }
                else if (m_collectedData.CurrentEdge.Type == AGXUnity.Edge.EdgeType.Principal)
                {
                    EdgeVisual.Color          = new Color(Color.red.r, Color.red.g, Color.red.b, defaultAlpha);
                    EdgeVisual.MouseOverColor = new Color(Color.red.r, Color.red.g, Color.red.b, mouseOverAlpha);
                }
            }

            NodeVisual.Visible = EdgeVisual.Visible && m_collectedData.SelectedEdge.Valid;
            if (NodeVisual.Visible)
            {
                const float nodeRadius = 0.040f;

                NodeVisual.SetTransform(m_collectedData.PointOnEdge, Quaternion.identity, nodeRadius);

                // The user doesn't have to hit the node sphere.
                if (Manager.HijackLeftMouseClick())
                {
                    OnPointClick(new Utils.Raycast.Result()
                    {
                        Hit = false
                    }, NodeVisual);
                }
            }
        }