public static Quaternion DoRotationHandle(Quaternion rotation, Vector3 position, bool snapping, CSGHandles.InitFunction initFunction, CSGHandles.InitFunction shutdownFunction = null)
        {
            int hotControl   = EditorGUIUtility.hotControl;
            int xAxisDiscID  = GUIUtility.GetControlID(s_DiscHash, FocusType.Keyboard);
            int yAxisDiscID  = GUIUtility.GetControlID(s_DiscHash, FocusType.Keyboard);
            int zAxisDiscID  = GUIUtility.GetControlID(s_DiscHash, FocusType.Keyboard);
            int freeDiscID   = GUIUtility.GetControlID(s_DiscHash, FocusType.Keyboard);
            int freeRotateID = GUIUtility.GetControlID(s_FreeRotateHandleHash, FocusType.Keyboard);

            bool haveControl = (hotControl == xAxisDiscID) ||
                               (hotControl == yAxisDiscID) ||
                               (hotControl == zAxisDiscID) ||
                               (hotControl == freeDiscID) ||
                               (hotControl == freeRotateID);


            float size = HandleUtility.GetHandleSize(position);
            Color temp = Handles.color;

            var isStatic = (!Tools.hidden && EditorApplication.isPlaying && ContainsStatic(Selection.gameObjects));

            Handles.color = isStatic ? Color.Lerp(Handles.xAxisColor, staticColor, staticBlend) : Handles.xAxisColor;
            if (!haveControl || hotControl == xAxisDiscID)
            {
                rotation = CSGDisc.Do(xAxisDiscID, "X", rotation, position, rotation * Vector3.right, size, true, snapping, RealtimeCSG.CSGSettings.SnapRotation, initFunction, shutdownFunction);
            }

            Handles.color = isStatic ? Color.Lerp(Handles.yAxisColor, staticColor, staticBlend) : Handles.yAxisColor;
            if (!haveControl || hotControl == yAxisDiscID)
            {
                rotation = CSGDisc.Do(yAxisDiscID, "Y", rotation, position, rotation * Vector3.up, size, true, snapping, RealtimeCSG.CSGSettings.SnapRotation, initFunction, shutdownFunction);
            }

            Handles.color = isStatic ? Color.Lerp(Handles.zAxisColor, staticColor, staticBlend) : Handles.zAxisColor;
            if (!haveControl || hotControl == zAxisDiscID)
            {
                rotation = CSGDisc.Do(zAxisDiscID, "Z", rotation, position, rotation * Vector3.forward, size, true, snapping, RealtimeCSG.CSGSettings.SnapRotation, initFunction, shutdownFunction);
            }

            if (!isStatic)
            {
                Handles.color = Handles.centerColor;
                if (!haveControl || hotControl == freeDiscID)
                {
                    rotation = CSGDisc.Do(freeDiscID, null, rotation, position, Camera.current.transform.forward, size * 1.1f, false, snapping, 0, initFunction, shutdownFunction);
                }

                if (!haveControl || hotControl == freeRotateID)
                {
                    rotation = CSGFreeRotate.Do(freeRotateID, rotation, position, size, snapping, initFunction, shutdownFunction);
                }
            }

            Handles.color = temp;
            return(rotation);
        }
        public static Quaternion FreeRotateHandle(Quaternion rotation, Vector3 position, float size, bool snapping, CSGHandles.InitFunction initFunction, CSGHandles.InitFunction shutdownFunction = null)
        {
            int id = GUIUtility.GetControlID(s_FreeRotateHandleHash, FocusType.Keyboard);

            return(CSGFreeRotate.Do(id, rotation, position, size, snapping, initFunction, shutdownFunction));
        }