Example #1
0
        public static ShapeExtrusionState Do(Rect dragArea, out Curve2D shape, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, Axis axis)
        {
            try
            {
                if (!s_ExtrusionMode)
                {
                    // TODO: handle snapping against own points
                    // TODO: handle ability to 'commit'
                    PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, releaseOnMouseUp: true, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap);

                    if (s_Points.Count <= 1)
                    {
                        return(ShapeExtrusionState.HoverMode);
                    }

                    if (s_Points.Count <= 3)
                    {
                        return(ShapeExtrusionState.ShapeMode);
                    }

                    if ((s_Points[s_Points.Count - 2] - s_Points[0]).sqrMagnitude < PointDrawing.kDistanceEpsilon)
                    {
                        s_ExtrusionMode = true;
                        s_Points[s_Points.Count - 1] = s_Points[0];
                        return(ShapeExtrusionState.Create);
                    }
                    return(ShapeExtrusionState.ShapeMode);
                }
                else
                {
                    var tempPoint = s_Points[s_Points.Count - 1];
                    var oldMatrix = UnityEditor.Handles.matrix;
                    UnityEditor.Handles.matrix = UnityEditor.Handles.matrix * s_Transformation;
                    var extrusionState = ExtrusionHandle.DoHandle(dragArea, ref tempPoint, axis);
                    UnityEditor.Handles.matrix   = oldMatrix;
                    s_Points[s_Points.Count - 1] = tempPoint;

                    switch (extrusionState)
                    {
                    case ExtrusionState.Cancel:             { s_ExtrusionMode = false; return(ShapeExtrusionState.Cancel); }

                    case ExtrusionState.Commit:             { s_ExtrusionMode = false; return(ShapeExtrusionState.Commit); }

                    case ExtrusionState.Modified:   { return(ShapeExtrusionState.Modified); }
                    }
                    return(ShapeExtrusionState.ExtrusionMode);
                }
            }
            finally
            {
                modelBeneathCursor = s_ModelBeneathCursor;
                transformation     = s_Transformation;
                shape  = GetShape();
                height = GetHeight(axis);
            }
        }
        public static BoxExtrusionState Do(Rect dragArea, out Bounds bounds, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, BoxExtrusionFlags flags, Axis axis, float?snappingSteps = null)
        {
            try
            {
                if (SceneHandles.InCameraOrbitMode)
                {
                    return(BoxExtrusionState.None);
                }

                if (s_Points.Count <= 2)
                {
                    PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap);

                    if (s_Points.Count <= 1)
                    {
                        return(BoxExtrusionState.HoverMode);
                    }

                    if (s_Points.Count > 2)
                    {
                        s_Points[2] = s_Points[0];
                        return(BoxExtrusionState.Create);
                    }

                    return(BoxExtrusionState.SquareMode);
                }
                else
                {
                    var tempPoint = s_Points[2];
                    var oldMatrix = UnityEditor.Handles.matrix;
                    UnityEditor.Handles.matrix = UnityEditor.Handles.matrix * s_Transformation;
                    var extrusionState = ExtrusionHandle.DoHandle(dragArea, ref tempPoint, axis, snappingSteps: snappingSteps);
                    UnityEditor.Handles.matrix = oldMatrix;
                    s_Points[2] = tempPoint;

                    switch (extrusionState)
                    {
                    case ExtrusionState.Cancel:             { return(BoxExtrusionState.Cancel); }

                    case ExtrusionState.Commit:             { return(BoxExtrusionState.Commit); }

                    case ExtrusionState.Modified:   { return(BoxExtrusionState.Modified); }
                    }
                    return(BoxExtrusionState.BoxMode);
                }
            }
            finally
            {
                modelBeneathCursor = s_ModelBeneathCursor;
                bounds             = GetBounds(flags, axis);
                height             = GetHeight(axis);

                var center = bounds.center;
                if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY)
                {
                    center[(int)axis] -= height * 0.5f;
                }

                transformation = s_Transformation * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one);

                center = Vector3.zero;
                if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY)
                {
                    center[(int)axis] = height * 0.5f;
                }
                bounds.center = center;
            }
        }
Example #3
0
        public static BoxExtrusionState Do(Rect dragArea, out Bounds bounds, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, BoxExtrusionFlags flags, Axis axis, float?snappingSteps = null)
        {
            try
            {
                if (SceneHandles.InCameraOrbitMode)
                {
                    return(BoxExtrusionState.None);
                }

                if (s_Points.Count <= 2)
                {
                    PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap);

                    if (s_Points.Count <= 1)
                    {
                        return(BoxExtrusionState.HoverMode);
                    }

                    if (s_Points.Count > 2)
                    {
                        s_Points[2] = s_Points[0];
                        return(BoxExtrusionState.Create);
                    }

                    return(BoxExtrusionState.SquareMode);
                }
                else
                {
                    var tempPoint = s_Points[2];
                    var oldMatrix = UnityEditor.Handles.matrix;
                    UnityEditor.Handles.matrix = UnityEditor.Handles.matrix * s_Transformation;
                    var extrusionState = ExtrusionHandle.DoHandle(dragArea, ref tempPoint, axis, snappingSteps: snappingSteps);
                    UnityEditor.Handles.matrix = oldMatrix;
                    s_Points[2] = tempPoint;

                    switch (extrusionState)
                    {
                    case ExtrusionState.Cancel:             { return(BoxExtrusionState.Cancel); }

                    case ExtrusionState.Commit:             { return(BoxExtrusionState.Commit); }

                    case ExtrusionState.Modified:   { return(BoxExtrusionState.Modified); }
                    }
                    return(BoxExtrusionState.BoxMode);
                }
            }
            finally
            {
                modelBeneathCursor = s_ModelBeneathCursor;
                bounds             = GetBounds(flags, axis);
                height             = GetHeight(axis);

                var center = bounds.center;
                if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY)
                {
                    center[(int)axis] -= height * 0.5f;
                }

                transformation = s_Transformation * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one);
#if true
                //if (height > 0)
                {
                    if ((flags & BoxExtrusionFlags.AlwaysFaceUp) == BoxExtrusionFlags.AlwaysFaceUp)
                    {
                        var currentUp      = transformation.MultiplyVector(Vector3.up);
                        var currentForward = transformation.MultiplyVector(Vector3.forward);
                        var currentRight   = transformation.MultiplyVector(Vector3.right);

                        var desiredUp = Grid.ActiveGrid.Up;

                        var dotX = Vector3.Dot(currentRight, desiredUp);
                        var dotY = Vector3.Dot(currentUp, desiredUp);
                        var dotZ = Vector3.Dot(currentForward, desiredUp);

                        var absDotX = Mathf.Abs(dotX);
                        var absDotY = Mathf.Abs(dotY);
                        var absDotZ = Mathf.Abs(dotZ);

                        if (absDotX > absDotZ)
                        {
                            if (absDotX > absDotY)
                            {
                                var size = bounds.size;
                                var t    = size.x; size.x = size.y; size.y = t;
                                bounds.size = size;
                                axis        = Axis.X;
                                var position = transformation.GetColumn(3);
                                transformation.SetColumn(3, new Vector4(0, 0, 0, 1));
                                transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
                                transformation *= new Matrix4x4(new Vector4(0, 1, 0, 0),
                                                                new Vector4(1, 0, 0, 0),
                                                                new Vector4(0, 0, 1, 0),
                                                                new Vector4(0, 0, 0, 1));
                                transformation.SetColumn(3, position);
                            }
                        }
                        else
                        {
                            if (absDotZ > absDotY)
                            {
                                var size = bounds.size;
                                var t    = size.z; size.z = size.y; size.y = t;
                                bounds.size = size;
                                axis        = Axis.Z;
                                var position = transformation.GetColumn(3);
                                transformation.SetColumn(3, new Vector4(0, 0, 0, 1));
                                transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
                                transformation *= new Matrix4x4(new Vector4(1, 0, 0, 0),
                                                                new Vector4(0, 0, 1, 0),
                                                                new Vector4(0, 1, 0, 0),
                                                                new Vector4(0, 0, 0, 1));
                                transformation.SetColumn(3, position);
                            }
                        }
                    }

                    if (!s_ModelBeneathCursor &&
                        (flags & BoxExtrusionFlags.AlwaysFaceCameraXZ) == BoxExtrusionFlags.AlwaysFaceCameraXZ)
                    {
                        // TODO: take grid orientation into account to decide what is "X" and what is "Z"
                        var currentForward = transformation.MultiplyVector(Vector3.forward);
                        var currentRight   = transformation.MultiplyVector(Vector3.right);
                        var cameraOffset   = Camera.current.transform.forward;
                        var cameraForward  = (new Vector3(cameraOffset.x, 0, cameraOffset.z)).normalized;
                        var dotZ           = Vector3.Dot(currentForward, cameraForward);
                        var dotX           = Vector3.Dot(currentRight, cameraForward);

                        var angle = 0;
                        if (Mathf.Abs(dotX) < Mathf.Abs(dotZ))
                        {
                            if (dotZ > 0)
                            {
                                angle += 180;
                            }
                        }
                        else
                        {
                            if (dotX < 0)
                            {
                                angle += 90;
                            }
                            else
                            {
                                angle -= 90;
                            }

                            if (axis == Axis.X)
                            {
                                axis = Axis.Z;
                            }
                            var size = bounds.size;
                            var t    = size.x; size.x = size.z; size.z = t;
                            bounds.size = size;
                        }

                        var position = transformation.GetColumn(3);
                        transformation.SetColumn(3, new Vector4(0, 0, 0, 1));
                        transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
                        transformation *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, angle, 0), Vector3.one);
                        transformation.SetColumn(3, position);
                    }
                }
#endif

                center = Vector3.zero;
                if ((flags & BoxExtrusionFlags.GenerateFromCenterY) != BoxExtrusionFlags.GenerateFromCenterY)
                {
                    center[(int)axis] = height * 0.5f;
                }
                bounds.center = center;
            }
        }
        public static GeneratorModeState Do(Rect dragArea, out Bounds bounds, out float height, out ChiselModel modelBeneathCursor, out Matrix4x4 transformation, PlacementFlags flags, Axis upAxis, float?snappingSteps = null)
        {
            // TODO: shift should do SameLengthXZ, shift control includes Y
            // TODO: fixed height should be possible to change sign

            // TODO: have some sort of click placement of previously used bounds (alt?)
            //bounds = s_LastBounds;

            bool doCommit = false;

            try
            {
                if (SceneHandles.InCameraOrbitMode)
                {
                    return(GeneratorModeState.None);
                }

                height = GetHeight(flags, upAxis);
                if (s_Points.Count <= 2)
                {
                    PointDrawing.PointDrawHandle(dragArea, ref s_Points, out s_Transformation, out s_ModelBeneathCursor, releaseOnMouseUp: false, UnitySceneExtensions.SceneHandles.OutlinedDotHandleCap);
                    if (s_Points.Count <= 1)
                    {
                        return(GeneratorModeState.None);
                    }
                }
                if (s_Points.Count > 2)
                {
                    if (!s_ModifyMode)
                    {
                        PointDrawing.Release();
                        if ((flags & PlacementFlags.HeightEqualsHalfXZ) == PlacementFlags.HeightEqualsHalfXZ ||
                            (flags & PlacementFlags.HeightEqualsXZ) == PlacementFlags.HeightEqualsXZ ||
                            (flags & PlacementFlags.UseLastHeight) == PlacementFlags.UseLastHeight)
                        {
                            if (height > 0)
                            {
                                s_ModifyMode = false;
                                doCommit     = true;
                                return(GeneratorModeState.Commit);
                            }
                        }

                        s_Points[2]  = s_Points[1];
                        s_ModifyMode = true;
                        return(GeneratorModeState.Update);
                    }
                    if (s_ModifyMode)
                    {
                        var oldMatrix = UnityEditor.Handles.matrix;
                        UnityEditor.Handles.matrix *= s_Transformation;
                        var tempPoint      = s_Points[2];
                        var extrusionState = ExtrusionHandle.DoHandle(ref tempPoint, upAxis, snappingSteps: snappingSteps);
                        s_Points[2] = tempPoint;
                        UnityEditor.Handles.matrix = oldMatrix;

                        switch (extrusionState)
                        {
                        case ExtrusionState.Cancel:     { s_ModifyMode = false; return(GeneratorModeState.Cancel); }

                        case ExtrusionState.Commit:
                        {
                            s_ModifyMode = false;
                            doCommit     = true;
                            return(GeneratorModeState.Commit);
                        }
                        }
                    }
                }
                return(GeneratorModeState.Update);
            }
            finally
            {
                modelBeneathCursor = s_ModelBeneathCursor;
                bounds             = GetBounds(flags, upAxis);
                height             = bounds.size[(int)upAxis];

                var center = bounds.center;
                if ((flags & PlacementFlags.GenerateFromCenterY) != PlacementFlags.GenerateFromCenterY)
                {
                    center[(int)upAxis] -= height * 0.5f;
                }

                transformation = s_Transformation * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one);
#if true
                //if (height > 0)
                {
                    if ((flags & PlacementFlags.AlwaysFaceUp) == PlacementFlags.AlwaysFaceUp)
                    {
                        var currentUp      = transformation.MultiplyVector(Vector3.up);
                        var currentForward = transformation.MultiplyVector(Vector3.forward);
                        var currentRight   = transformation.MultiplyVector(Vector3.right);

                        var desiredUp = Grid.ActiveGrid.Up;

                        var dotX = Vector3.Dot(currentRight, desiredUp);
                        var dotY = Vector3.Dot(currentUp, desiredUp);
                        var dotZ = Vector3.Dot(currentForward, desiredUp);

                        var absDotX = Mathf.Abs(dotX);
                        var absDotY = Mathf.Abs(dotY);
                        var absDotZ = Mathf.Abs(dotZ);

                        if (absDotX > absDotZ)
                        {
                            if (absDotX > absDotY)
                            {
                                var size = bounds.size;
                                var t    = size.x; size.x = size.y; size.y = t;
                                bounds.size = size;
                                upAxis      = Axis.X;
                                var position = transformation.GetColumn(3);
                                transformation.SetColumn(3, new Vector4(0, 0, 0, 1));
                                transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
                                transformation *= new Matrix4x4(new Vector4(0, 1, 0, 0),
                                                                new Vector4(1, 0, 0, 0),
                                                                new Vector4(0, 0, 1, 0),
                                                                new Vector4(0, 0, 0, 1));
                                transformation.SetColumn(3, position);
                            }
                        }
                        else
                        {
                            if (absDotZ > absDotY)
                            {
                                var size = bounds.size;
                                var t    = size.z; size.z = size.y; size.y = t;
                                bounds.size = size;
                                upAxis      = Axis.Z;
                                var position = transformation.GetColumn(3);
                                transformation.SetColumn(3, new Vector4(0, 0, 0, 1));
                                transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
                                transformation *= new Matrix4x4(new Vector4(1, 0, 0, 0),
                                                                new Vector4(0, 0, 1, 0),
                                                                new Vector4(0, 1, 0, 0),
                                                                new Vector4(0, 0, 0, 1));
                                transformation.SetColumn(3, position);
                            }
                        }
                    }

                    if (!s_ModelBeneathCursor &&
                        (flags & PlacementFlags.AlwaysFaceCameraXZ) == PlacementFlags.AlwaysFaceCameraXZ)
                    {
                        // TODO: take grid orientation into account to decide what is "X" and what is "Z"
                        var currentForward = transformation.MultiplyVector(Vector3.forward);
                        var currentRight   = transformation.MultiplyVector(Vector3.right);
                        var cameraOffset   = Camera.current.transform.forward;
                        var cameraForward  = (new Vector3(cameraOffset.x, 0, cameraOffset.z)).normalized;
                        var dotZ           = Vector3.Dot(currentForward, cameraForward);
                        var dotX           = Vector3.Dot(currentRight, cameraForward);

                        var angle = 0;
                        if (Mathf.Abs(dotX) < Mathf.Abs(dotZ))
                        {
                            if (dotZ > 0)
                            {
                                angle += 180;
                            }
                        }
                        else
                        {
                            if (dotX < 0)
                            {
                                angle += 90;
                            }
                            else
                            {
                                angle -= 90;
                            }

                            if (upAxis == Axis.X)
                            {
                                upAxis = Axis.Z;
                            }
                            var size = bounds.size;
                            var t    = size.x; size.x = size.z; size.z = t;
                            bounds.size = size;
                        }

                        var position = transformation.GetColumn(3);
                        transformation.SetColumn(3, new Vector4(0, 0, 0, 1));
                        transformation *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);
                        transformation *= Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, angle, 0), Vector3.one);
                        transformation.SetColumn(3, position);
                    }
                }
#endif

                center = Vector3.zero;
                if ((flags & PlacementFlags.GenerateFromCenterY) != PlacementFlags.GenerateFromCenterY)
                {
                    center[(int)upAxis] = height * 0.5f;
                }
                else
                {
                    center[(int)upAxis] = 0;
                }
                bounds.center = center;
                if (doCommit)
                {
                    s_LastBounds = bounds;
                    s_LastHeight = s_NextHeight;
                }
            }
        }