コード例 #1
0
ファイル: CSGGrid.cs プロジェクト: matthewRitter/GolfIt
        public static Vector3 SnapDeltaRelative(Camera camera, Vector3 worldDeltaMovement, bool snapToGridPlane = true)
        {
            UpdateGridOrientation(camera);
            if (gridOrientation == null)
            {
                return(worldDeltaMovement);
            }

            var worldPlane  = gridOrientation.gridWorkPlane;
            var scaleVector = gridOrientation.gridSnapScale;
            var snapVector  = gridOrientation.gridSnapVector;

            var gridLocalDeltaMovement = VectorToGridSpace(worldDeltaMovement);
            var gridLocalPlane         = PlaneToGridSpace(worldPlane);

            if (snapToGridPlane)
            {
                scaleVector.x *= (Mathf.Abs(gridLocalPlane.a) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
                scaleVector.y *= (Mathf.Abs(gridLocalPlane.b) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
                scaleVector.z *= (Mathf.Abs(gridLocalPlane.c) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
            }
            var snappedDeltaMovement = gridLocalDeltaMovement;

            if (snapToGridPlane)
            {
                snappedDeltaMovement = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, snappedDeltaMovement);
            }
            snappedDeltaMovement = GridUtility.CleanPosition(snappedDeltaMovement);

            snappedDeltaMovement = SnapRoundPosition(snappedDeltaMovement, snapVector);

            if (snapToGridPlane)
            {
                snappedDeltaMovement = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, snappedDeltaMovement);
            }
            snappedDeltaMovement = GridUtility.CleanPosition(snappedDeltaMovement);


            snappedDeltaMovement.x *= scaleVector.x;
            snappedDeltaMovement.y *= scaleVector.y;
            snappedDeltaMovement.z *= scaleVector.z;

            worldDeltaMovement = VectorFromGridSpace(snappedDeltaMovement);
            return(worldDeltaMovement);
        }
コード例 #2
0
ファイル: GeometryUtility.cs プロジェクト: pdm1996/Fragsurf-2
        public static void MoveControlMeshVertices(CSGBrush[] brushes, Vector3 offset)
        {
            for (int b = 0; b < brushes.Length; b++)
            {
                var controlMesh = brushes[b].ControlMesh;
                if (controlMesh == null ||
                    controlMesh.Vertices == null)
                {
                    continue;
                }

                var localOffset = brushes[b].transform.worldToLocalMatrix.MultiplyVector(offset);
                for (var p = 0; p < controlMesh.Vertices.Length; p++)
                {
                    controlMesh.Vertices[p] = GridUtility.CleanPosition(controlMesh.Vertices[p] + localOffset);
                }
            }
        }
コード例 #3
0
ファイル: GeometryUtility.cs プロジェクト: pdm1996/Fragsurf-2
        public static void MoveControlMeshVertices(CSGBrush brush, Vector3 offset)
        {
            if (!brush)
            {
                return;
            }

            var controlMesh = brush.ControlMesh;

            if (controlMesh == null ||
                controlMesh.Vertices == null)
            {
                return;
            }

            var localOffset = brush.transform.worldToLocalMatrix.MultiplyVector(offset);

            for (var p = 0; p < controlMesh.Vertices.Length; p++)
            {
                controlMesh.Vertices[p] = GridUtility.CleanPosition(controlMesh.Vertices[p] + localOffset);
            }
        }
コード例 #4
0
        static void OnGUIContents(bool isSceneGUI, EditModePlace tool)
        {
            EditModeCommonGUI.StartToolGUI();

            var filteredSelection   = EditModeManager.FilteredSelection;
            var defaultMoveOffset   = CSGSettings.DefaultMoveOffset;
            var defaultRotateOffset = CSGSettings.DefaultRotateOffset;
            var displayNewCenter    = GridUtility.CleanPosition((Tools.pivotRotation == PivotRotation.Local) ?
                                                                tool.LocalSpacePivotCenter :
                                                                tool.WorldSpacePivotCenter);

            GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty);
            {
                GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty);
                {
                    ShowCSGOperations(isSceneGUI, tool, filteredSelection);
                    GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty);
                    {
                        EditorGUI.BeginDisabledGroup(!tool.HaveSelection);
                        {
                            if (Tools.current == Tool.Move)
                            {
                                EditorGUI.BeginDisabledGroup(defaultMoveOffset.sqrMagnitude < MathConstants.EqualityEpsilonSqr);
                                {
                                    if (GUILayout.Button(MoveByOffsetContent))
                                    {
                                        tool.MoveByOffset(RealtimeCSG.CSGSettings.DefaultMoveOffset);
                                    }
                                    TooltipUtility.SetToolTip(MoveByOffsetTooltip);
                                    if (GUILayout.Button(CloneMoveByOffsetContent))
                                    {
                                        tool.CloneMoveByOffset(RealtimeCSG.CSGSettings.DefaultMoveOffset);
                                    }
                                    TooltipUtility.SetToolTip(CloneMoveByOffsetTooltip);
                                }
                                EditorGUI.EndDisabledGroup();
                            }
                            else
                            if (Tools.current == Tool.Rotate)
                            {
                                EditorGUI.BeginDisabledGroup(defaultMoveOffset.sqrMagnitude < MathConstants.EqualityEpsilonSqr);
                                {
                                    if (GUILayout.Button(RotateByOffsetContent))
                                    {
                                        tool.RotateByOffset(Quaternion.Euler(RealtimeCSG.CSGSettings.DefaultRotateOffset));
                                    }
                                    TooltipUtility.SetToolTip(RotateByOffsetTooltip);
                                    if (GUILayout.Button(CloneRotateByOffsetContent))
                                    {
                                        tool.CloneRotateByOffset(Quaternion.Euler(RealtimeCSG.CSGSettings.DefaultRotateOffset));
                                    }
                                    TooltipUtility.SetToolTip(CloneRotateByOffsetTooltip);
                                }
                                EditorGUI.EndDisabledGroup();
                                if (GUILayout.Button(RecenterPivotContent))
                                {
                                    tool.RecenterPivot();
                                }
                                TooltipUtility.SetToolTip(RecenterPivotTooltip);
                            }
                        }
                        EditorGUI.EndDisabledGroup();
                    }
                    GUILayout.EndVertical();
                }
                GUILayout.EndHorizontal();
                GUILayout.Space(5);
                if (Tools.current == Tool.Move)
                {
                    var doubleFieldOptions = isSceneGUI ? MaxWidth150 : CSG_GUIStyleUtility.ContentEmpty;
                    EditorGUI.BeginDisabledGroup(!tool.HaveSelection);
                    {
                        EditorGUI.BeginChangeCheck();
                        {
                            GUILayout.Label(MoveOffsetContent);
                            defaultMoveOffset = CSG_EditorGUIUtility.DistanceVector3Field(defaultMoveOffset, false, doubleFieldOptions);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            RealtimeCSG.CSGSettings.DefaultMoveOffset = defaultMoveOffset;
                            RealtimeCSG.CSGSettings.Save();
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }
                else
                if (Tools.current == Tool.Rotate)
                {
                    var doubleFieldOptions = isSceneGUI ? MaxWidth150 : CSG_GUIStyleUtility.ContentEmpty;
                    EditorGUI.BeginDisabledGroup(Tools.pivotMode == PivotMode.Center || !tool.HaveSelection);
                    {
                        EditorGUI.BeginChangeCheck();
                        {
                            GUILayout.Label(RotationCenterContent);
                            defaultRotateOffset = CSG_EditorGUIUtility.EulerDegreeField(defaultRotateOffset);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            RealtimeCSG.CSGSettings.DefaultRotateOffset = defaultRotateOffset;
                            RealtimeCSG.CSGSettings.Save();
                        }

                        EditorGUI.BeginChangeCheck();
                        {
                            GUILayout.Label(PivotCenterContent);
                            displayNewCenter = CSG_EditorGUIUtility.DistanceVector3Field(displayNewCenter, false, doubleFieldOptions);
                            TooltipUtility.SetToolTip(PivotVectorTooltip);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            if (Tools.pivotRotation == PivotRotation.Local)
                            {
                                tool.LocalSpacePivotCenter = displayNewCenter;
                            }
                            else
                            {
                                tool.WorldSpacePivotCenter = displayNewCenter;
                            }
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }
            }
            GUILayout.EndVertical();
            EditorGUI.showMixedValue = false;
        }
コード例 #5
0
ファイル: CSGGrid.cs プロジェクト: matthewRitter/GolfIt
        public static Vector3 SnapDeltaToRayGrid(Camera camera, Ray worldRay, Vector3 worldDeltaMovement, Vector3[] worldPoints, bool snapToSelf = false)
        {
            UpdateGridOrientation(camera);
            if (gridOrientation == null || worldPoints == null || worldPoints.Length == 0)
            {
                return(worldDeltaMovement);
            }

            var snapVector  = gridOrientation.gridSnapVector;
            var scaleVector = gridOrientation.gridSnapScale;

            var localDeltaMovement = VectorToGridSpace(worldDeltaMovement);
            var localLineDir       = VectorToGridSpace(worldRay.direction);
            var localLineOrg       = PointToGridSpace(worldRay.origin);

            scaleVector.x *= ((Mathf.Abs(localLineDir.y) >= 1 - MathConstants.EqualityEpsilon) || (Mathf.Abs(localLineDir.z) >= 1 - MathConstants.EqualityEpsilon)) ? 0 : 1;
            scaleVector.y *= ((Mathf.Abs(localLineDir.x) >= 1 - MathConstants.EqualityEpsilon) || (Mathf.Abs(localLineDir.z) >= 1 - MathConstants.EqualityEpsilon)) ? 0 : 1;
            scaleVector.z *= ((Mathf.Abs(localLineDir.x) >= 1 - MathConstants.EqualityEpsilon) || (Mathf.Abs(localLineDir.y) >= 1 - MathConstants.EqualityEpsilon)) ? 0 : 1;

            var snappedDeltaMovement = localDeltaMovement;

            if (Mathf.Abs(scaleVector.x) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.x = 0;
            }
            if (Mathf.Abs(scaleVector.y) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.y = 0;
            }
            if (Mathf.Abs(scaleVector.z) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.z = 0;
            }

            Vector3[] localPoints;
            if (worldPoints.Length > 1)
            {
                var bounds = new AABB();
                bounds.Reset();
                for (int i = 0; i < worldPoints.Length; i++)
                {
                    var localPoint = GeometryUtility.ProjectPointOnInfiniteLine(PointToGridSpace(worldPoints[i]), localLineOrg, localLineDir);
                    bounds.Extend(localPoint);
                }
                localPoints = bounds.GetCorners();
            }
            else
            {
                localPoints = new Vector3[] { GeometryUtility.ProjectPointOnInfiniteLine(PointToGridSpace(worldPoints[0]), localLineOrg, localLineDir) };
            }

            for (int i = 0; i < localPoints.Length; i++)
            {
                var oldPoint = localPoints[i];
                var newPoint = GeometryUtility.ProjectPointOnInfiniteLine(oldPoint + localDeltaMovement, localLineOrg, localLineDir);

                var snappedNewPoint = SnapRoundPosition(newPoint, snapVector);

                snappedNewPoint = GridUtility.CleanPosition(GeometryUtility.ProjectPointOnInfiniteLine(snappedNewPoint, localLineOrg, localLineDir));

                var foundDeltaMovement = (snappedNewPoint - oldPoint);

                foundDeltaMovement.x *= scaleVector.x;
                foundDeltaMovement.y *= scaleVector.y;
                foundDeltaMovement.z *= scaleVector.z;

                if (i == 0 || Math.Abs(foundDeltaMovement.x) < Mathf.Abs(snappedDeltaMovement.x))
                {
                    snappedDeltaMovement.x = foundDeltaMovement.x;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.y) < Mathf.Abs(snappedDeltaMovement.y))
                {
                    snappedDeltaMovement.y = foundDeltaMovement.y;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.z) < Mathf.Abs(snappedDeltaMovement.z))
                {
                    snappedDeltaMovement.z = foundDeltaMovement.z;
                }
            }

            if (snapToSelf)
            {
                var snapDelta = (snappedDeltaMovement - localDeltaMovement);
                if (Mathf.Abs(snapDelta.x) > Mathf.Abs(localDeltaMovement.x))
                {
                    snappedDeltaMovement.x = 0;
                }
                if (Mathf.Abs(snapDelta.y) > Mathf.Abs(localDeltaMovement.y))
                {
                    snappedDeltaMovement.y = 0;
                }
                if (Mathf.Abs(snapDelta.z) > Mathf.Abs(localDeltaMovement.z))
                {
                    snappedDeltaMovement.z = 0;
                }
            }

            worldDeltaMovement = VectorFromGridSpace(snappedDeltaMovement);
            return(worldDeltaMovement);
        }
コード例 #6
0
ファイル: CSGGrid.cs プロジェクト: matthewRitter/GolfIt
        public static Vector3 SnapDeltaToGrid(Camera camera, Vector3 worldDeltaMovement, Vector3[] worldPoints, bool snapToGridPlane = true, bool snapToSelf = false)
        {
            UpdateGridOrientation(camera);
            if (gridOrientation == null || worldPoints == null || worldPoints.Length == 0)
            {
                return(worldDeltaMovement);
            }

            var worldPlane  = gridOrientation.gridWorkPlane;
            var scaleVector = gridOrientation.gridSnapScale;
            var snapVector  = gridOrientation.gridSnapVector;

            var gridLocalDeltaMovement = VectorToGridSpace(worldDeltaMovement);
            var gridLocalPlane         = PlaneToGridSpace(worldPlane);

            if (snapToGridPlane)
            {
                scaleVector.x *= (Mathf.Abs(gridLocalPlane.a) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
                scaleVector.y *= (Mathf.Abs(gridLocalPlane.b) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
                scaleVector.z *= (Mathf.Abs(gridLocalPlane.c) >= 1 - MathConstants.EqualityEpsilon) ? 0 : 1;
            }
            var snappedDeltaMovement = gridLocalDeltaMovement;

            if (Mathf.Abs(scaleVector.x) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.x = 0;
            }
            if (Mathf.Abs(scaleVector.y) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.y = 0;
            }
            if (Mathf.Abs(scaleVector.z) < MathConstants.EqualityEpsilon)
            {
                snappedDeltaMovement.z = 0;
            }

            Vector3[] gridLocalPoints;
            if (worldPoints.Length > 1)
            {
                var bounds = new AABB();
                bounds.Reset();
                for (int i = 0; i < worldPoints.Length; i++)
                {
                    Vector3 localPoint = PointToGridSpace(worldPoints[i]);
                    if (snapToGridPlane)
                    {
                        localPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, localPoint);
                    }
                    if (float.IsNaN(localPoint.x) || float.IsNaN(localPoint.y) || float.IsNaN(localPoint.z) ||
                        float.IsInfinity(localPoint.x) || float.IsInfinity(localPoint.y) || float.IsInfinity(localPoint.z))
                    {
                        continue;
                    }
                    bounds.Extend(localPoint);
                }
                gridLocalPoints = bounds.GetCorners();
            }
            else
            {
                var     localGridSpacePoint = PointToGridSpace(worldPoints[0]);
                Vector3 projectedPoint      = localGridSpacePoint;
                if (snapToGridPlane)
                {
                    projectedPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, localGridSpacePoint);
                }

                if (float.IsNaN(projectedPoint.x) || float.IsNaN(projectedPoint.y) || float.IsNaN(projectedPoint.z) ||
                    float.IsInfinity(projectedPoint.x) || float.IsInfinity(projectedPoint.y) || float.IsInfinity(projectedPoint.z))
                {
                    gridLocalPoints = new Vector3[0] {
                    }
                }
                ;
                else
                {
                    gridLocalPoints = new Vector3[] { projectedPoint }
                };
            }

            for (int i = 0; i < gridLocalPoints.Length; i++)
            {
                var oldPoint = gridLocalPoints[i];
                var newPoint = gridLocalPoints[i] + gridLocalDeltaMovement;
                if (snapToGridPlane)
                {
                    newPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, newPoint);
                }
                newPoint = GridUtility.CleanPosition(newPoint);

                var snappedNewPoint = SnapRoundPosition(newPoint, snapVector);

                if (snapToGridPlane)
                {
                    snappedNewPoint = GeometryUtility.ProjectPointOnPlane(gridLocalPlane, snappedNewPoint);
                }
                snappedNewPoint = GridUtility.CleanPosition(snappedNewPoint);

                var foundDeltaMovement = (snappedNewPoint - oldPoint);

                foundDeltaMovement.x *= scaleVector.x;
                foundDeltaMovement.y *= scaleVector.y;
                foundDeltaMovement.z *= scaleVector.z;

                if (i == 0 || Math.Abs(foundDeltaMovement.x) < Mathf.Abs(snappedDeltaMovement.x))
                {
                    snappedDeltaMovement.x = foundDeltaMovement.x;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.y) < Mathf.Abs(snappedDeltaMovement.y))
                {
                    snappedDeltaMovement.y = foundDeltaMovement.y;
                }
                if (i == 0 || Math.Abs(foundDeltaMovement.z) < Mathf.Abs(snappedDeltaMovement.z))
                {
                    snappedDeltaMovement.z = foundDeltaMovement.z;
                }
            }

            if (snapToSelf)
            {
                var snapDelta = (snappedDeltaMovement - gridLocalDeltaMovement);
                if (Mathf.Abs(snapDelta.x) > Mathf.Abs(gridLocalDeltaMovement.x))
                {
                    snappedDeltaMovement.x = 0;
                }
                if (Mathf.Abs(snapDelta.y) > Mathf.Abs(gridLocalDeltaMovement.y))
                {
                    snappedDeltaMovement.y = 0;
                }
                if (Mathf.Abs(snapDelta.z) > Mathf.Abs(gridLocalDeltaMovement.z))
                {
                    snappedDeltaMovement.z = 0;
                }
            }

            worldDeltaMovement = VectorFromGridSpace(snappedDeltaMovement);
            return(worldDeltaMovement);
        }
コード例 #7
0
        static public Vector3 FixPosition(Vector3 currentPosition, Matrix4x4 worldToLocalMatrix, Matrix4x4 localToWorldMatrix, Vector3 previousPosition, bool ignoreAxisLocking = false)
        {
            if (currentPosition == previousPosition)
            {
                return(currentPosition);
            }

            var pivotRotation = UnityEditor.Tools.pivotRotation;

            if (pivotRotation == UnityEditor.PivotRotation.Local)
            {
                previousPosition = worldToLocalMatrix.MultiplyPoint(previousPosition);
                currentPosition  = worldToLocalMatrix.MultiplyPoint(currentPosition);

                if (!ignoreAxisLocking)
                {
                    if (RealtimeCSG.CSGSettings.LockAxisX)
                    {
                        currentPosition.x = previousPosition.x;
                    }
                    if (RealtimeCSG.CSGSettings.LockAxisY)
                    {
                        currentPosition.y = previousPosition.y;
                    }
                    if (RealtimeCSG.CSGSettings.LockAxisZ)
                    {
                        currentPosition.z = previousPosition.z;
                    }
                }

                var doGridSnapping = RealtimeCSG.CSGSettings.GridSnapping;
                if (doGridSnapping)
                {
                    if (Mathf.Abs(currentPosition.x - previousPosition.x) < MathConstants.EqualityEpsilon)
                    {
                        currentPosition.x = previousPosition.x;
                    }
                    if (Mathf.Abs(currentPosition.y - previousPosition.y) < MathConstants.EqualityEpsilon)
                    {
                        currentPosition.y = previousPosition.y;
                    }
                    if (Mathf.Abs(currentPosition.z - previousPosition.z) < MathConstants.EqualityEpsilon)
                    {
                        currentPosition.z = previousPosition.z;
                    }

                    if (currentPosition.x != previousPosition.x)
                    {
                        currentPosition.x = Mathf.Round(currentPosition.x / RealtimeCSG.CSGSettings.SnapVector.x) * RealtimeCSG.CSGSettings.SnapVector.x;
                    }
                    if (currentPosition.y != previousPosition.y)
                    {
                        currentPosition.y = Mathf.Round(currentPosition.y / RealtimeCSG.CSGSettings.SnapVector.y) * RealtimeCSG.CSGSettings.SnapVector.y;
                    }
                    if (currentPosition.z != previousPosition.z)
                    {
                        currentPosition.z = Mathf.Round(currentPosition.z / RealtimeCSG.CSGSettings.SnapVector.z) * RealtimeCSG.CSGSettings.SnapVector.z;
                    }
                }

                currentPosition = localToWorldMatrix.MultiplyPoint(currentPosition);
            }
            else
            {
                if (!ignoreAxisLocking)
                {
                    if (RealtimeCSG.CSGSettings.LockAxisX)
                    {
                        currentPosition.x = previousPosition.x;
                    }
                    if (RealtimeCSG.CSGSettings.LockAxisY)
                    {
                        currentPosition.y = previousPosition.y;
                    }
                    if (RealtimeCSG.CSGSettings.LockAxisZ)
                    {
                        currentPosition.z = previousPosition.z;
                    }
                }

                if (RealtimeCSG.CSGSettings.GridSnapping)
                {
                    if (currentPosition.x != previousPosition.x)
                    {
                        currentPosition.x = Mathf.Round(currentPosition.x / RealtimeCSG.CSGSettings.SnapVector.x) * RealtimeCSG.CSGSettings.SnapVector.x;
                    }
                    if (currentPosition.y != previousPosition.y)
                    {
                        currentPosition.y = Mathf.Round(currentPosition.y / RealtimeCSG.CSGSettings.SnapVector.y) * RealtimeCSG.CSGSettings.SnapVector.y;
                    }
                    if (currentPosition.z != previousPosition.z)
                    {
                        currentPosition.z = Mathf.Round(currentPosition.z / RealtimeCSG.CSGSettings.SnapVector.z) * RealtimeCSG.CSGSettings.SnapVector.z;
                    }
                }
            }

            currentPosition = GridUtility.CleanPosition(currentPosition);
            return(currentPosition);
        }
コード例 #8
0
ファイル: ObjectToolGUI.cs プロジェクト: wwm0nkey/ProjectSym
        static void OnGUIContents(bool isSceneGUI, ObjectEditBrushTool tool)
        {
            CommonGUI.StartToolGUI();

            var filteredSelection   = CSGBrushEditorManager.FilteredSelection;
            var defaultMoveOffset   = CSGSettings.DefaultMoveOffset;
            var defaultRotateOffset = CSGSettings.DefaultRotateOffset;
            var displayNewCenter    = GridUtility.CleanPosition((Tools.pivotRotation == PivotRotation.Local) ?
                                                                tool.LocalSpacePivotCenter :
                                                                tool.WorldSpacePivotCenter);

            GUILayout.BeginVertical(GUIStyleUtility.ContentEmpty);
            {
                GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty);
                {
                    HandleCSGOperations(isSceneGUI, tool, filteredSelection);
                    GUILayout.BeginVertical(GUIStyleUtility.ContentEmpty);
                    {
                        EditorGUI.BeginDisabledGroup(!tool.HaveSelection);
                        {
                            if (Tools.current == Tool.Move)
                            {
                                EditorGUI.BeginDisabledGroup(defaultMoveOffset.sqrMagnitude < MathConstants.EqualityEpsilonSqr);
                                {
                                    if (GUILayout.Button(MoveByOffsetContent))
                                    {
                                        tool.MoveByOffset(RealtimeCSG.CSGSettings.DefaultMoveOffset);
                                    }
                                    TooltipUtility.SetToolTip(MoveByOffsetTooltip);
                                    if (GUILayout.Button(CloneMoveByOffsetContent))
                                    {
                                        tool.CloneMoveByOffset(RealtimeCSG.CSGSettings.DefaultMoveOffset);
                                    }
                                    TooltipUtility.SetToolTip(CloneMoveByOffsetTooltip);
                                }
                                EditorGUI.EndDisabledGroup();
                            }
                            else
                            if (Tools.current == Tool.Rotate)
                            {
                                EditorGUI.BeginDisabledGroup(defaultMoveOffset.sqrMagnitude < MathConstants.EqualityEpsilonSqr);
                                {
                                    if (GUILayout.Button(RotateByOffsetContent))
                                    {
                                        tool.RotateByOffset(Quaternion.Euler(RealtimeCSG.CSGSettings.DefaultRotateOffset));
                                    }
                                    TooltipUtility.SetToolTip(RotateByOffsetTooltip);
                                    if (GUILayout.Button(CloneRotateByOffsetContent))
                                    {
                                        tool.CloneRotateByOffset(Quaternion.Euler(RealtimeCSG.CSGSettings.DefaultRotateOffset));
                                    }
                                    TooltipUtility.SetToolTip(CloneRotateByOffsetTooltip);
                                }
                                EditorGUI.EndDisabledGroup();
                                if (GUILayout.Button(RecenterPivotContent))
                                {
                                    tool.RecenterPivot();
                                }
                                TooltipUtility.SetToolTip(RecenterPivotTooltip);
                            }
                        }
                        EditorGUI.EndDisabledGroup();
                    }
                    GUILayout.EndVertical();
                }
                GUILayout.EndHorizontal();
                GUILayout.Space(5);
                if (Tools.current == Tool.Move)
                {
                    var doubleFieldOptions = isSceneGUI ? MaxWidth150 : GUIStyleUtility.ContentEmpty;
                    EditorGUI.BeginDisabledGroup(!tool.HaveSelection);
                    {
                        EditorGUI.BeginChangeCheck();
                        {
                            GUILayout.Label("Offset");
                            defaultMoveOffset = GUIStyleUtility.DistanceVector3Field(defaultMoveOffset, false, doubleFieldOptions);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            RealtimeCSG.CSGSettings.DefaultMoveOffset = defaultMoveOffset;
                            RealtimeCSG.CSGSettings.Save();
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }
                else
                if (Tools.current == Tool.Rotate)
                {
                    var doubleFieldOptions = isSceneGUI ? MaxWidth150 : GUIStyleUtility.ContentEmpty;
                    EditorGUI.BeginDisabledGroup(Tools.pivotMode == PivotMode.Center || !tool.HaveSelection);
                    {
                        EditorGUI.BeginChangeCheck();
                        {
                            GUILayout.Label("Offset");
                            defaultRotateOffset = GUIStyleUtility.EulerDegreeField(defaultRotateOffset);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            RealtimeCSG.CSGSettings.DefaultRotateOffset = defaultRotateOffset;
                            RealtimeCSG.CSGSettings.Save();
                        }

                        EditorGUI.BeginChangeCheck();
                        {
                            GUILayout.Label("Pivot");
                            displayNewCenter = GUIStyleUtility.DistanceVector3Field(displayNewCenter, false, doubleFieldOptions);
                            TooltipUtility.SetToolTip(PivotVectorTooltip);
                        }
                        if (EditorGUI.EndChangeCheck())
                        {
                            if (Tools.pivotRotation == PivotRotation.Local)
                            {
                                tool.LocalSpacePivotCenter = displayNewCenter;
                            }
                            else
                            {
                                tool.WorldSpacePivotCenter = displayNewCenter;
                            }
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }

                /*
                 * if (Tools.current != Tool.Rotate)
                 * {
                 *      if (!isSceneGUI || !SceneView.currentDrawingSceneView.camera.orthographic)
                 *      {
                 *              if (!isSceneGUI)
                 *              {
                 *                      GUILayout.Space(10);
                 *                      GUILayout.Label("Tips", EditorStyles.miniLabel);
                 *              }
                 *
                 *              GUILayout.BeginVertical(isSceneGUI ? GUI.skin.box : GUIStyle.none);
                 *              {
                 *                      GUILayout.Label(Keys.VerticalMoveMode.ToString() + " to drag brush up/down", EditorStyles.miniLabel);
                 *              }
                 *              GUILayout.EndVertical();
                 *      }
                 * }
                 */
            }
            GUILayout.EndVertical();
            EditorGUI.showMixedValue = false;
        }