Esempio n. 1
0
        void SetupInputPlane(Vector2 mousePosition)
        {
            plane = EditorHandleUtility.FindBestPlane(mousePosition);

            var planeNormal = plane.normal;
            var planeCenter = plane.normal * -plane.distance;

            // if hit point on plane is cardinal axis and on grid, snap to grid.
            if (Math.IsCardinalAxis(planeNormal))
            {
                const float epsilon = .00001f;
                bool        offGrid = false;
                Vector3     snapVal = EditorSnapping.activeMoveSnapValue;
                Vector3     center  = Vector3.Scale(ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(planeNormal), planeCenter);
                for (int i = 0; i < 3; i++)
                {
                    offGrid |= Mathf.Abs(snapVal[i] % center[i]) > epsilon;
                }
                polygon.isOnGrid = !offGrid;
            }
            else
            {
                polygon.isOnGrid = false;
            }
        }
Esempio n. 2
0
        static void DoSizeHandles(ProBuilderShape proBuilderShape, bool updatePrefs)
        {
            int faceCount = s_Faces.Length;

            var evt = Event.current;

            var is2D = proBuilderShape.shape is Plane || proBuilderShape.shape is Sprite;

            for (int i = 0; i < faceCount; i++)
            {
                var face = faces[i];
                if (is2D && !face.IsValid)
                {
                    continue;
                }

                if (Event.current.type == EventType.Repaint)
                {
                    Color color = k_BoundsHandleColor;
                    color.a *= face.IsVisible ? 1f : 0.5f;
                    using (new Handles.DrawingScope(color))
                    {
                        int pointsCount = face.Points.Length;
                        for (int k = 0; k < pointsCount; k++)
                        {
                            Handles.DrawLine(face.Points[k], face.Points[(k + 1) % pointsCount]);
                        }
                    }
                }

                if (DoFaceSizeHandle(face, s_FaceControlIDs[i]))
                {
                    if (!s_SizeManipulationInit)
                    {
                        s_StartCenter          = proBuilderShape.transform.position + proBuilderShape.transform.TransformVector(proBuilderShape.shapeBox.center);
                        s_StartScale           = proBuilderShape.transform.lossyScale;
                        s_StartScaleInverse    = new Vector3(1f / Mathf.Abs(s_StartScale.x), 1f / Mathf.Abs(s_StartScale.y), 1f / Mathf.Abs(s_StartScale.z));
                        s_StartPositionLocal   = face.CenterPosition;
                        s_StartPositionGlobal  = proBuilderShape.transform.TransformPoint(Vector3.Scale(face.CenterPosition, s_StartScale));
                        s_StartSize            = proBuilderShape.size;
                        s_SizeManipulationInit = true;
                        s_Scaling = Vector3.Scale(face.Normal, Math.Sign(s_StartSize));
                    }

                    var targetSize = s_StartSize;
                    if (Math.IsCardinalAxis(proBuilderShape.transform.up) &&
                        EditorSnapSettings.gridSnapEnabled &&
                        !EditorSnapSettings.incrementalSnapActive &&
                        !evt.alt)
                    {
                        var faceDelta    = (s_SizeDelta * s_Faces[i].Normal);
                        var facePosition = s_StartPositionGlobal + faceDelta;
                        facePosition = ProBuilderSnapping.Snap(facePosition, EditorSnapping.activeMoveSnapValue);
                        targetSize  += Vector3.Scale((facePosition - s_StartPositionGlobal), s_Scaling);
                    }
                    else
                    {
                        //Should we expand on the 2 sides?
                        var modifier = evt.alt ? 2f : 1f;
                        var delta    = modifier * (s_SizeDelta * s_Faces[i].Normal);
                        delta.Scale(s_Scaling);
                        delta.Scale(s_StartScaleInverse);

                        targetSize += delta;
                        var snap = EditorSnapSettings.incrementalSnapActive
                            ? Vector3.Scale(EditorSnapping.activeMoveSnapValue, Math.Abs(face.Normal))
                            : Vector3.zero;

                        targetSize = ProBuilderSnapping.Snap(targetSize, snap);
                    }

                    var center = Vector3.zero;
                    if (!evt.alt)
                    {
                        center = Vector3.Scale((targetSize - s_StartSize) / 2f, s_Scaling);
                        center = Vector3.Scale(center, Math.Sign(s_StartScale));
                        center = proBuilderShape.transform.TransformVector(center);
                    }

                    ApplyProperties(proBuilderShape, s_StartCenter + center, targetSize);

                    if (updatePrefs)
                    {
                        DrawShapeTool.SaveShapeParams(proBuilderShape);
                    }
                }
            }
        }
        public override ShapeState DoState(Event evt)
        {
            if (evt.type == EventType.KeyDown)
            {
                switch (evt.keyCode)
                {
                case KeyCode.Escape:
                    ToolManager.RestorePreviousTool();
                    break;
                }
            }

            if (tool.m_LastShapeCreated != null)
            {
                EditShapeTool.DoEditingHandles(tool.m_LastShapeCreated, true);
            }

            if (evt.isMouse && HandleUtility.nearestControl == tool.controlID)
            {
                var res = EditorHandleUtility.FindBestPlaneAndBitangent(evt.mousePosition);

                Ray   ray = HandleUtility.GUIPointToWorldRay(evt.mousePosition);
                float hit;

                if (res.item1.Raycast(ray, out hit))
                {
                    //Plane init
                    tool.m_Plane        = res.item1;
                    tool.m_PlaneForward = res.item2;
                    tool.m_PlaneRight   = Vector3.Cross(tool.m_Plane.normal, tool.m_PlaneForward);

                    var planeNormal = tool.m_Plane.normal;
                    var planeCenter = tool.m_Plane.normal * -tool.m_Plane.distance;
                    // if hit point on plane is cardinal axis and on grid, snap to grid.
                    if (Math.IsCardinalAxis(planeNormal))
                    {
                        const float epsilon = .00001f;
                        bool        offGrid = false;
                        Vector3     snapVal = EditorSnapping.activeMoveSnapValue;
                        Vector3     center  =
                            Vector3.Scale(ProBuilderSnapping.GetSnappingMaskBasedOnNormalVector(planeNormal),
                                          planeCenter);
                        for (int i = 0; i < 3; i++)
                        {
                            offGrid |= Mathf.Abs(snapVal[i] % center[i]) > epsilon;
                        }
                        tool.m_IsOnGrid = !offGrid;
                    }
                    else
                    {
                        tool.m_IsOnGrid = false;
                    }

                    m_HitPosition = tool.GetPoint(ray.GetPoint(hit));

                    //Click has been done => Define a plane for the tool
                    if (evt.type == EventType.MouseDown)
                    {
                        //BB init
                        tool.m_BB_Origin         = m_HitPosition;
                        tool.m_BB_HeightCorner   = tool.m_BB_Origin;
                        tool.m_BB_OppositeCorner = tool.m_BB_Origin;

                        return(NextState());
                    }
                }
                else
                {
                    m_HitPosition = Vector3.negativeInfinity;
                }
            }

            if (GUIUtility.hotControl == 0 && evt.shift && !(evt.control || evt.command))
            {
                tool.DuplicatePreview(m_HitPosition);
            }
            else if (tool.m_DuplicateGO != null)
            {
                Object.DestroyImmediate(tool.m_DuplicateGO);
            }

            // Repaint to visualize the placement preview dot
            if (evt.type == EventType.MouseMove && HandleUtility.nearestControl == tool.controlID)
            {
                HandleUtility.Repaint();
            }

            if (evt.type == EventType.Repaint)
            {
                if (GUIUtility.hotControl == 0 && HandleUtility.nearestControl == tool.controlID)
                {
                    using (new Handles.DrawingScope(EditorHandleDrawing.vertexSelectedColor))
                    {
                        Handles.DotHandleCap(-1, m_HitPosition, Quaternion.identity,
                                             HandleUtility.GetHandleSize(m_HitPosition) * 0.05f, EventType.Repaint);
                    }
                }

                if (GUIUtility.hotControl == 0 && evt.shift && !(evt.control || evt.command))
                {
                    tool.DrawBoundingBox(false);
                }
            }

            return(this);
        }
        static void DoSizeHandles(ProBuilderShape proBuilderShape, bool updatePrefs)
        {
            int faceCount = s_Faces.Length;

            var evt = Event.current;

            var is2D = proBuilderShape.shape is Plane || proBuilderShape.shape is Sprite;

            for (int i = 0; i < faceCount; i++)
            {
                var face = faces[i];
                if (is2D && !face.IsValid)
                {
                    continue;
                }

                if (Event.current.type == EventType.Repaint)
                {
                    Color color = k_BoundsHandleColor;
                    color.a *= face.IsVisible ? 1f : 0.5f;
                    using (new Handles.DrawingScope(color))
                    {
                        int pointsCount = face.Points.Length;
                        for (int k = 0; k < pointsCount; k++)
                        {
                            Handles.DrawLine(face.Points[k], face.Points[(k + 1) % pointsCount]);
                        }
                    }
                }

                if (DoFaceSizeHandle(face))
                {
                    float modifier = 1f;
                    if (evt.alt)
                    {
                        modifier = 2f;
                    }

                    if (!s_SizeManipulationInit)
                    {
                        s_StartCenter          = proBuilderShape.transform.position + proBuilderShape.transform.TransformVector(proBuilderShape.shapeBox.center);
                        s_StartPosition        = face.CenterPosition;
                        s_StartSize            = proBuilderShape.size;
                        s_SizeManipulationInit = true;

                        s_Scaling = Vector3.Scale(face.Normal, Math.Sign(s_StartSize));
                    }

                    var targetDelta = modifier * (s_TargetSize - s_StartPosition);
                    targetDelta.Scale(s_Scaling);

                    var targetSize = s_StartSize + targetDelta;

                    var snap = Math.IsCardinalAxis(proBuilderShape.transform.up) && EditorSnapSettings.gridSnapEnabled ?
                               EditorSnapping.activeMoveSnapValue :
                               Vector3.zero;
                    targetSize = ProBuilderSnapping.Snap(targetSize, snap);

                    var center = Vector3.zero;
                    if (!evt.alt)
                    {
                        center = Vector3.Scale((targetSize - s_StartSize) / 2f, s_Scaling);
                        center = Vector3.Scale(center, Math.Sign(proBuilderShape.transform.lossyScale));
                        center = proBuilderShape.transform.TransformVector(center);
                    }

                    ApplyProperties(proBuilderShape, s_StartCenter + center, targetSize);

                    if (updatePrefs)
                    {
                        DrawShapeTool.SaveShapeParams(proBuilderShape);
                    }
                }
            }
        }