From 7521cd7d1c2cc3b9d097d702567aedbd74b2c387 Mon Sep 17 00:00:00 2001 From: Daniel Cornelius Date: Thu, 27 Jan 2022 13:47:54 -0600 Subject: [PATCH] Fix SceneView UI layout issues with 2021.2+ (#330) * Fix SceneView UI layout issues with 2021.2+ * implement fixes suggested by @andreiagmu, clean up UI this implements fixes suggested by @andreiagmu and removes the sliders in the generator popups, in favor of `[<] [>]` buttons, which removes the bugginess of unity sliders in the scene view. * removed redundant/unused imports or braces, fixed compilation errors on versions < 2021.2 * Revert "Merge branch 'master' into 2021.2-update" This reverts commit 762822bf7e32b7d9fe98d2c5212d05af256efa96, reversing changes made to 142008a16c721f9c6246bbc4bb93854a6897ea66. * Merge pull request #328 from epiplon-game-studio/master Fixes a reference error bug with play mode * revert changes from upstream, which adjusts the Y offset of the toolbar. This is now handled automatically by unity, with `rootVisualElement.contentRect`, causing the upstream changes to do nothing. * Update EditModeToolWindow.Editor.cs * Update EditModeToolWindow.Editor.cs * Delete ProjectVersion.txt --- .gitignore | 1 + .../InternalCSGModelManager.DefaultModel.cs | 12 +- .../Control/Managers/SceneViewEventHandler.cs | 150 ++--- .../Scripts/Control/Managers/UpdateLoop.cs | 443 ++++++++------- .../Editor/Scripts/Utility/PrefabUtility.cs | 182 +++---- .../View/GUI/EditModeGUI/EditModeManager.cs | 2 +- .../GUI/EditModeGUI/EditModeSelection.GUI.cs | 2 +- .../EditModeGUI/EditModeToolWindow.Editor.cs | 11 +- .../Generators/Generator.Cylinder.GUI.cs | 514 +++++++++--------- .../Generator.Cylinder.GUIContents.cs | 57 +- .../Generators/Generator.Sphere.GUI.cs | 403 +++++++------- .../Generator.Sphere.GUIContents.cs | 42 +- .../SceneViewBottomBar.GUI.cs | 13 +- .../GUI/SceneViewInfoGUI/SceneViewInfo.GUI.cs | 4 +- .../SceneViewInfo.GUIContents.cs | 37 +- RealtimeCSG/Packages/manifest.json | 39 ++ RealtimeCSG/Packages/packages-lock.json | 306 +++++++++++ .../ProjectSettings/MemorySettings.asset | 35 ++ .../PackageManagerSettings.asset | 35 ++ .../ProjectSettings/PresetManager.asset | 7 + .../ProjectSettings/ProjectSettings.asset | Bin 52530 -> 70330 bytes .../ProjectSettings/ProjectVersion.txt | 1 - RealtimeCSG/ProjectSettings/VFXManager.asset | 15 + RealtimeCSG/ProjectSettings/boot.config | 0 24 files changed, 1400 insertions(+), 911 deletions(-) create mode 100644 RealtimeCSG/Packages/manifest.json create mode 100644 RealtimeCSG/Packages/packages-lock.json create mode 100644 RealtimeCSG/ProjectSettings/MemorySettings.asset create mode 100644 RealtimeCSG/ProjectSettings/PackageManagerSettings.asset create mode 100644 RealtimeCSG/ProjectSettings/PresetManager.asset delete mode 100644 RealtimeCSG/ProjectSettings/ProjectVersion.txt create mode 100644 RealtimeCSG/ProjectSettings/VFXManager.asset create mode 100644 RealtimeCSG/ProjectSettings/boot.config diff --git a/.gitignore b/.gitignore index db1f37a..cf32c39 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ [Bb]uild/ [Bb]uilds/ Assets/AssetStoreTools* +UserSettings* # Visual Studio cache directory .vs/ diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/InternalCSGModelManager.DefaultModel.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/InternalCSGModelManager.DefaultModel.cs index 8624b28..9ab789c 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/InternalCSGModelManager.DefaultModel.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/InternalCSGModelManager.DefaultModel.cs @@ -88,14 +88,12 @@ static void InitializeDefaultCSGModel(Scene currentScene, CSGSceneState sceneSta bool inPrefabMode = false; Transform prefabRootTransform = null; #if UNITY_2018_3_OR_NEWER - -#if UNITY_2021_2_OR_NEWER - var currentPrefabStage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); -#else + #if !UNITY_2021_2_OR_NEWER var currentPrefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); -#endif - - if (currentPrefabStage != null) + #else + var currentPrefabStage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); + #endif +if (currentPrefabStage != null) { var prefabRoot = currentPrefabStage.prefabContentsRoot; prefabRootTransform = prefabRoot.transform; diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/SceneViewEventHandler.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/SceneViewEventHandler.cs index 4337f26..1c5319d 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/SceneViewEventHandler.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/SceneViewEventHandler.cs @@ -9,87 +9,97 @@ using UnityEngine.SceneManagement; using RealtimeCSG.Helpers; + namespace RealtimeCSG { - internal sealed class SceneViewEventHandler - { - static bool mousePressed; + internal sealed class SceneViewEventHandler + { + static bool mousePressed; static int prevFocusControl; - internal static void OnScene(SceneView sceneView) - { - CSGSettings.RegisterSceneView(sceneView); - if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG) - return; - - if (EditorApplication.isPlayingOrWillChangePlaymode) - return; - UpdateLoop.UpdateOnSceneChange(); - - if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG) - ColorSettings.isInitialized = false; - else - if (!ColorSettings.isInitialized) - { - if (Event.current.type == EventType.Repaint) - { - ColorSettings.Update(); - } - } - - if (!UpdateLoop.IsActive()) - UpdateLoop.ResetUpdateRoutine(); - - if (Event.current.type == EventType.MouseDown || - Event.current.type == EventType.MouseDrag) { mousePressed = true; } - else if (Event.current.type == EventType.MouseUp || - Event.current.type == EventType.MouseMove) { mousePressed = false; } - - SceneDragToolManager.OnHandleDragAndDrop(sceneView); - RectangleSelectionManager.Update(sceneView); - EditModeManager.InitSceneGUI(sceneView); - - if (Event.current.type == EventType.Repaint) - MeshInstanceManager.UpdateHelperSurfaces(); - - if (Event.current.type == EventType.Repaint) - { - SceneToolRenderer.OnPaint(sceneView); - } else - //if (fallbackGUI) - { - SceneViewBottomBarGUI.ShowGUI(sceneView); + internal static void OnScene( SceneView sceneView ) + { + CSGSettings.RegisterSceneView( sceneView ); + + if( !RealtimeCSG.CSGSettings.EnableRealtimeCSG ) + return; + + if( EditorApplication.isPlayingOrWillChangePlaymode ) + return; + + UpdateLoop.UpdateOnSceneChange(); + + if( !RealtimeCSG.CSGSettings.EnableRealtimeCSG ) + ColorSettings.isInitialized = false; + else if( !ColorSettings.isInitialized ) + { + if( Event.current.type == EventType.Repaint ) + { + ColorSettings.Update(); + } + } + + if( !UpdateLoop.IsActive() ) + UpdateLoop.ResetUpdateRoutine(); + + if( Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag ) + { + mousePressed = true; + } + else if( Event.current.type == EventType.MouseUp || Event.current.type == EventType.MouseMove ) + { + mousePressed = false; + } + + SceneDragToolManager.OnHandleDragAndDrop( sceneView ); + RectangleSelectionManager.Update( sceneView ); + EditModeManager.InitSceneGUI( sceneView ); + + if( Event.current.type == EventType.Repaint ) + MeshInstanceManager.UpdateHelperSurfaces(); + + if( Event.current.type == EventType.Repaint ) + { + SceneToolRenderer.OnPaint( sceneView ); + } + else + //if (fallbackGUI) + { + SceneViewBottomBarGUI.ShowGUI( sceneView ); SceneViewInfoGUI.DrawInfoGUI( sceneView ); - } - - EditModeManager.OnSceneGUI(sceneView); - - //if (fallbackGUI) - { - TooltipUtility.InitToolTip(sceneView); - if (Event.current.type == EventType.Repaint) - { - SceneViewBottomBarGUI.ShowGUI(sceneView); - SceneViewInfoGUI.DrawInfoGUI( sceneView ); - } - if (!mousePressed) - { - Handles.BeginGUI(); - TooltipUtility.DrawToolTip(getLastRect: false); - Handles.EndGUI(); - } - } - - if (Event.current.type == EventType.Layout) + } + + EditModeManager.OnSceneGUI( sceneView ); + + //if (fallbackGUI) + { + TooltipUtility.InitToolTip( sceneView ); + + if( Event.current.type == EventType.Repaint ) + { + SceneViewBottomBarGUI.ShowGUI( sceneView, false ); + SceneViewInfoGUI.DrawInfoGUI( sceneView ); + } + + if( !mousePressed ) + { + Handles.BeginGUI(); + TooltipUtility.DrawToolTip( getLastRect: false ); + Handles.EndGUI(); + } + } + + if( Event.current.type == EventType.Layout ) { var currentFocusControl = CSGHandles.FocusControl; - if (prevFocusControl != currentFocusControl) + + if( prevFocusControl != currentFocusControl ) { prevFocusControl = currentFocusControl; HandleUtility.Repaint(); } } - } - } + } + } } diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/UpdateLoop.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/UpdateLoop.cs index 5e053ee..3203150 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/UpdateLoop.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Control/Managers/UpdateLoop.cs @@ -11,52 +11,52 @@ namespace RealtimeCSG { - [InitializeOnLoad] - internal sealed class UpdateLoop - { - [MenuItem("Edit/Realtime-CSG/Turn Realtime-CSG on or off %F3", false, 30)] - static void ToggleRealtimeCSG() - { - RealtimeCSG.CSGSettings.SetRealtimeCSGEnabled(!RealtimeCSG.CSGSettings.EnableRealtimeCSG); - } - - public static bool IsActive() { return (editor != null && editor.initialized); } - - - static UpdateLoop editor = null; - static UpdateLoop() - { - if (editor != null) - { - editor.Shutdown(); - editor = null; - } - editor = new UpdateLoop(); - editor.Initialize(); - } - - bool initialized = false; - bool had_first_update = false; - - void Initialize() - { - if (initialized) - return; + [InitializeOnLoad] + internal sealed class UpdateLoop + { + [MenuItem("Edit/Realtime-CSG/Turn Realtime-CSG on or off %F3", false, 30)] + static void ToggleRealtimeCSG() + { + RealtimeCSG.CSGSettings.SetRealtimeCSGEnabled(!RealtimeCSG.CSGSettings.EnableRealtimeCSG); + } + + public static bool IsActive() { return (editor != null && editor.initialized); } + + + static UpdateLoop editor = null; + static UpdateLoop() + { + if (editor != null) + { + editor.Shutdown(); + editor = null; + } + editor = new UpdateLoop(); + editor.Initialize(); + } - CSGKeysPreferenceWindow.ReadKeys(); + bool initialized = false; + bool had_first_update = false; - initialized = true; + void Initialize() + { + if (initialized) + return; - CSGSceneManagerRedirector.Interface = new CSGSceneManagerInstance(); + CSGKeysPreferenceWindow.ReadKeys(); - Selection.selectionChanged -= OnSelectionChanged; - Selection.selectionChanged += OnSelectionChanged; + initialized = true; + + CSGSceneManagerRedirector.Interface = new CSGSceneManagerInstance(); + + Selection.selectionChanged -= OnSelectionChanged; + Selection.selectionChanged += OnSelectionChanged; - EditorApplication.update -= OnFirstUpdate; - EditorApplication.update += OnFirstUpdate; + EditorApplication.update -= OnFirstUpdate; + EditorApplication.update += OnFirstUpdate; #if UNITY_2018_1_OR_NEWER - EditorApplication.hierarchyChanged -= OnHierarchyWindowChanged; + EditorApplication.hierarchyChanged -= OnHierarchyWindowChanged; EditorApplication.hierarchyChanged += OnHierarchyWindowChanged; #else @@ -64,20 +64,19 @@ void Initialize() EditorApplication.hierarchyWindowChanged += OnHierarchyWindowChanged; #endif -#if UNITY_2018_3_OR_NEWER - #if UNITY_2021_2_OR_NEWER +#if UNITY_2021_2_OR_NEWER // SceneManagement.PrefabStage was moved out of experimental in 2021.2 UnityEditor.SceneManagement.PrefabStage.prefabSaving += OnPrefabSaving; - #else - UnityEditor.Experimental.SceneManagement.PrefabStage.prefabSaving += OnPrefabSaving; +#else + #if UNITY_2018_3_OR_NEWER // SceneManagement.PrefabStage was introduced in 2018.3 with nested prefabs + UnityEditor.Experimental.SceneManagement.PrefabStage.prefabSaving += OnPrefabSaving; #endif - #endif - EditorApplication.hierarchyWindowItemOnGUI -= HierarchyWindowItemGUI.OnHierarchyWindowItemOnGUI; - EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemGUI.OnHierarchyWindowItemOnGUI; - - UnityCompilerDefineManager.UpdateUnityDefines(); - } + EditorApplication.hierarchyWindowItemOnGUI -= HierarchyWindowItemGUI.OnHierarchyWindowItemOnGUI; + EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItemGUI.OnHierarchyWindowItemOnGUI; + + UnityCompilerDefineManager.UpdateUnityDefines(); + } #if UNITY_2018_3_OR_NEWER private void OnPrefabSaving(GameObject obj) @@ -88,142 +87,142 @@ private void OnPrefabSaving(GameObject obj) void Shutdown(bool finalizing = false) - { - if (editor != this) - return; + { + if (editor != this) + return; - editor = null; - CSGSceneManagerRedirector.Interface = null; - if (!initialized) - return; + editor = null; + CSGSceneManagerRedirector.Interface = null; + if (!initialized) + return; - EditorApplication.update -= OnFirstUpdate; + EditorApplication.update -= OnFirstUpdate; #if UNITY_2018_1_OR_NEWER - EditorApplication.hierarchyChanged -= OnHierarchyWindowChanged; + EditorApplication.hierarchyChanged -= OnHierarchyWindowChanged; #else EditorApplication.hierarchyWindowChanged -= OnHierarchyWindowChanged; #endif - EditorApplication.hierarchyWindowItemOnGUI -= HierarchyWindowItemGUI.OnHierarchyWindowItemOnGUI; + EditorApplication.hierarchyWindowItemOnGUI -= HierarchyWindowItemGUI.OnHierarchyWindowItemOnGUI; #if UNITY_2019_1_OR_NEWER - SceneView.duringSceneGui -= SceneViewEventHandler.OnScene; + SceneView.duringSceneGui -= SceneViewEventHandler.OnScene; #else SceneView.onSceneGUIDelegate -= SceneViewEventHandler.OnScene; #endif - Undo.undoRedoPerformed -= UndoRedoPerformed; + Undo.undoRedoPerformed -= UndoRedoPerformed; - initialized = false; + initialized = false; - // make sure the C++ side of things knows to clear the method pointers - // so that we don't accidentally use them while closing unity - NativeMethodBindings.ClearUnityMethods(); - NativeMethodBindings.ClearExternalMethods(); + // make sure the C++ side of things knows to clear the method pointers + // so that we don't accidentally use them while closing unity + NativeMethodBindings.ClearUnityMethods(); + NativeMethodBindings.ClearExternalMethods(); - if (!finalizing) - SceneToolRenderer.Cleanup(); - } + if (!finalizing) + SceneToolRenderer.Cleanup(); + } - static Scene currentScene; - internal static void UpdateOnSceneChange() - { - if (EditorApplication.isPlayingOrWillChangePlaymode) - return; - - var activeScene = SceneManager.GetActiveScene(); - if (currentScene != activeScene) - { - if (editor == null) - ResetUpdateRoutine(); - - editor.OnSceneUnloaded(); - currentScene = activeScene; - InternalCSGModelManager.InitOnNewScene(); - } - } - - void OnSceneUnloaded() - { - if (EditorApplication.isPlayingOrWillChangePlaymode) - return; - - if (this.initialized) - this.Shutdown(); - - MeshInstanceManager.Shutdown(); - InternalCSGModelManager.Shutdown(); - - editor = new UpdateLoop(); - editor.Initialize(); - } + static Scene currentScene; + internal static void UpdateOnSceneChange() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) + return; - public static void EnsureFirstUpdate() - { - if (editor == null) - return; - if (!editor.had_first_update) - editor.OnFirstUpdate(); - } - - void OnHierarchyWindowChanged() - { - if (EditorApplication.isPlayingOrWillChangePlaymode) - return; - - SceneDragToolManager.UpdateDragAndDrop(); - InternalCSGModelManager.UpdateHierarchy(); - } - - void UndoRedoPerformed() - { - InternalCSGModelManager.UndoRedoPerformed(); - } - - // Delegate for generic updates - void OnFirstUpdate() - { - had_first_update = true; - EditorApplication.update -= OnFirstUpdate; - RealtimeCSG.CSGSettings.Reload(); - - // register unity methods in the c++ code so that some unity functions - // (such as debug.log) can be called from within the c++ code. - NativeMethodBindings.RegisterUnityMethods(); - - // register dll methods so we can use them - NativeMethodBindings.RegisterExternalMethods(); - - RunOnce(); - //CreateSceneChangeDetector(); - } + var activeScene = SceneManager.GetActiveScene(); + if (currentScene != activeScene) + { + if (editor == null) + ResetUpdateRoutine(); - void RunOnce() - { - if (EditorApplication.isPlayingOrWillChangePlaymode) - { - // when you start playing the game in the editor, it'll call - // RunOnce before playing the game, but not after. - // so we need to wait until the game has stopped, after which we'll - // run first update again. - EditorApplication.update -= OnWaitUntillStoppedPlaying; - EditorApplication.update += OnWaitUntillStoppedPlaying; - return; - } + editor.OnSceneUnloaded(); + currentScene = activeScene; + InternalCSGModelManager.InitOnNewScene(); + } + } + + void OnSceneUnloaded() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) + return; + + if (this.initialized) + this.Shutdown(); + + MeshInstanceManager.Shutdown(); + InternalCSGModelManager.Shutdown(); + + editor = new UpdateLoop(); + editor.Initialize(); + } + + public static void EnsureFirstUpdate() + { + if (editor == null) + return; + if (!editor.had_first_update) + editor.OnFirstUpdate(); + } + + void OnHierarchyWindowChanged() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) + return; + + SceneDragToolManager.UpdateDragAndDrop(); + InternalCSGModelManager.UpdateHierarchy(); + } + + void UndoRedoPerformed() + { + InternalCSGModelManager.UndoRedoPerformed(); + } + + // Delegate for generic updates + void OnFirstUpdate() + { + had_first_update = true; + EditorApplication.update -= OnFirstUpdate; + RealtimeCSG.CSGSettings.Reload(); + + // register unity methods in the c++ code so that some unity functions + // (such as debug.log) can be called from within the c++ code. + NativeMethodBindings.RegisterUnityMethods(); + + // register dll methods so we can use them + NativeMethodBindings.RegisterExternalMethods(); + + RunOnce(); + //CreateSceneChangeDetector(); + } + + void RunOnce() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) + { + // when you start playing the game in the editor, it'll call + // RunOnce before playing the game, but not after. + // so we need to wait until the game has stopped, after which we'll + // run first update again. + EditorApplication.update -= OnWaitUntillStoppedPlaying; + EditorApplication.update += OnWaitUntillStoppedPlaying; + return; + } #if UNITY_2019_1_OR_NEWER - SceneView.duringSceneGui -= SceneViewEventHandler.OnScene; - SceneView.duringSceneGui += SceneViewEventHandler.OnScene; + SceneView.duringSceneGui -= SceneViewEventHandler.OnScene; + SceneView.duringSceneGui += SceneViewEventHandler.OnScene; #else SceneView.onSceneGUIDelegate -= SceneViewEventHandler.OnScene; SceneView.onSceneGUIDelegate += SceneViewEventHandler.OnScene; #endif - Undo.undoRedoPerformed -= UndoRedoPerformed; - Undo.undoRedoPerformed += UndoRedoPerformed; - - // InternalCSGModelManager.UpdateHierarchy(); - - // but .. why? - /* + Undo.undoRedoPerformed -= UndoRedoPerformed; + Undo.undoRedoPerformed += UndoRedoPerformed; + +// InternalCSGModelManager.UpdateHierarchy(); + + // but .. why? + /* var scene = SceneManager.GetActiveScene(); var allGeneratedMeshes = SceneQueryUtility.GetAllComponentsInScene(scene); for (int i = 0; i < allGeneratedMeshes.Count; i++) @@ -233,71 +232,71 @@ void RunOnce() } */ - // we use a co-routine for updates because EditorApplication.update - // works at a ridiculous rate and the co-routine is only fired in the - // editor when something has happened. - ResetUpdateRoutine(); - } + // we use a co-routine for updates because EditorApplication.update + // works at a ridiculous rate and the co-routine is only fired in the + // editor when something has happened. + ResetUpdateRoutine(); + } - void OnWaitUntillStoppedPlaying() - { - if (!EditorApplication.isPlaying) - { - EditorApplication.update -= OnWaitUntillStoppedPlaying; + void OnWaitUntillStoppedPlaying() + { + if (!EditorApplication.isPlaying) + { + EditorApplication.update -= OnWaitUntillStoppedPlaying; - EditorApplication.update -= OnFirstUpdate; - EditorApplication.update += OnFirstUpdate; - } - } + EditorApplication.update -= OnFirstUpdate; + EditorApplication.update += OnFirstUpdate; + } + } + + static void RunEditorUpdate() + { + if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG) + return; + + if (EditorApplication.isPlayingOrWillChangePlaymode) + return; + + UpdateLoop.UpdateOnSceneChange(); + + try + { + if (!ColorSettings.isInitialized) + ColorSettings.Update(); + InternalCSGModelManager.CheckForChanges(forceHierarchyUpdate: false); + TooltipUtility.CleanCache(); + } + catch (Exception ex) + { + Debug.LogException(ex); + } + } - static void RunEditorUpdate() - { - if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG) - return; - - if (EditorApplication.isPlayingOrWillChangePlaymode) - return; - - UpdateLoop.UpdateOnSceneChange(); - - try - { - if (!ColorSettings.isInitialized) - ColorSettings.Update(); - InternalCSGModelManager.CheckForChanges(forceHierarchyUpdate: false); - TooltipUtility.CleanCache(); - } - catch (Exception ex) - { - Debug.LogException(ex); - } - } + public static void ResetUpdateRoutine() + { + if (EditorApplication.isPlayingOrWillChangePlaymode) + return; - public static void ResetUpdateRoutine() - { - if (EditorApplication.isPlayingOrWillChangePlaymode) - return; - - if (editor != null && - !editor.initialized) - { - editor = null; - } - if (editor == null) - { - editor = new UpdateLoop(); - editor.Initialize(); - } - - EditorApplication.update -= RunEditorUpdate; - EditorApplication.update += RunEditorUpdate; - InternalCSGModelManager.skipCheckForChanges = false; - } + if (editor != null && + !editor.initialized) + { + editor = null; + } + if (editor == null) + { + editor = new UpdateLoop(); + editor.Initialize(); + } + EditorApplication.update -= RunEditorUpdate; + EditorApplication.update += RunEditorUpdate; + InternalCSGModelManager.skipCheckForChanges = false; + } - static void OnSelectionChanged() - { - EditModeManager.UpdateSelection(); - } - } + + static void OnSelectionChanged() + { + EditModeManager.UpdateSelection(); + } + } } \ No newline at end of file diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Utility/PrefabUtility.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Utility/PrefabUtility.cs index a26264e..4484efd 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Utility/PrefabUtility.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/Utility/PrefabUtility.cs @@ -8,13 +8,13 @@ namespace RealtimeCSG { public sealed class CSGPrefabUtility { - public static UnityEngine.Object GetCorrespondingObjectFromSource(UnityEngine.Object source) - { -#if UNITY_2018_2_OR_NEWER - return PrefabUtility.GetCorrespondingObjectFromSource(source); -#else + public static UnityEngine.Object GetCorrespondingObjectFromSource(UnityEngine.Object source) + { + #if UNITY_2018_2_OR_NEWER + return PrefabUtility.GetCorrespondingObjectFromSource(source); + #else return PrefabUtility.GetPrefabParent(source); -#endif + #endif } public static bool IsPrefab(CSGModel model) @@ -31,18 +31,18 @@ public static bool IsPrefab(CSGModel model) public static bool AreInPrefabMode() { -#if UNITY_2018_3_OR_NEWER && UNITY_EDITOR + #if UNITY_2018_3_OR_NEWER && UNITY_EDITOR var mainStage = StageUtility.GetMainStageHandle(); var currentStageHandle = StageUtility.GetCurrentStageHandle(); if (mainStage != currentStageHandle) return true; -#endif + #endif return false; } public static bool IsEditedInPrefabMode(CSGModel model) { -#if UNITY_2018_3_OR_NEWER && UNITY_EDITOR + #if UNITY_2018_3_OR_NEWER && UNITY_EDITOR if (!model) return false; @@ -52,139 +52,139 @@ public static bool IsEditedInPrefabMode(CSGModel model) var currentStageHandle = StageUtility.GetCurrentStageHandle(); if (currentStageHandle.Contains(model.gameObject)) return true; -#endif + #endif return false; } public static CSGNode[] GetNodesInPrefabMode() { -#if UNITY_2018_3_OR_NEWER && UNITY_EDITOR + #if UNITY_2018_3_OR_NEWER && UNITY_EDITOR var mainStage = StageUtility.GetMainStageHandle(); var currentStageHandle = StageUtility.GetCurrentStageHandle(); if (mainStage != currentStageHandle) return currentStageHandle.FindComponentsOfType(); -#endif + #endif return null; } public static bool IsPrefabAssetOrInstance(GameObject gameObject) - { -#if UNITY_2018_3_OR_NEWER - var prefabAssetType = PrefabUtility.GetPrefabAssetType(gameObject); - var prefabInstanceType = PrefabUtility.GetPrefabInstanceStatus(gameObject); - if (prefabAssetType == PrefabAssetType.NotAPrefab && - prefabInstanceType == PrefabInstanceStatus.NotAPrefab) - return false; - return true; -#else + { + #if UNITY_2018_3_OR_NEWER + var prefabAssetType = PrefabUtility.GetPrefabAssetType(gameObject); + var prefabInstanceType = PrefabUtility.GetPrefabInstanceStatus(gameObject); + if (prefabAssetType == PrefabAssetType.NotAPrefab && + prefabInstanceType == PrefabInstanceStatus.NotAPrefab) + return false; + return true; + #else var prefabType = PrefabUtility.GetPrefabType(gameObject); if (prefabType == PrefabType.None) return false; return true; -#endif - } - - public static bool IsPrefabAsset(GameObject gameObject) - { -#if UNITY_2018_3_OR_NEWER - var prefabInstanceType = PrefabUtility.GetPrefabInstanceStatus(gameObject); - if (prefabInstanceType != PrefabInstanceStatus.NotAPrefab) - return false; - - var prefabType = PrefabUtility.GetPrefabAssetType(gameObject); - return prefabType != PrefabAssetType.NotAPrefab && - prefabType != PrefabAssetType.Model; -#else + #endif + } + + public static bool IsPrefabAsset(GameObject gameObject) + { + #if UNITY_2018_3_OR_NEWER + var prefabInstanceType = PrefabUtility.GetPrefabInstanceStatus(gameObject); + if (prefabInstanceType != PrefabInstanceStatus.NotAPrefab) + return false; + + var prefabType = PrefabUtility.GetPrefabAssetType(gameObject); + return prefabType != PrefabAssetType.NotAPrefab && + prefabType != PrefabAssetType.Model; + #else var prefabType = PrefabUtility.GetPrefabType(gameObject); if (prefabType == PrefabType.None) return false; return (prefabType == PrefabType.Prefab || prefabType == PrefabType.ModelPrefab); -#endif - } - - public static bool IsPrefabInstance(GameObject gameObject) - { -#if UNITY_2018_3_OR_NEWER + #endif + } + + public static bool IsPrefabInstance(GameObject gameObject) + { + #if UNITY_2018_3_OR_NEWER if (!PrefabUtility.IsPartOfAnyPrefab(gameObject)) return false; var prefabType = PrefabUtility.GetPrefabInstanceStatus(gameObject); - return prefabType != PrefabInstanceStatus.NotAPrefab; -#else + return prefabType != PrefabInstanceStatus.NotAPrefab; + #else var prefabType = PrefabUtility.GetPrefabType(gameObject); if (prefabType == PrefabType.None) return false; return (prefabType != PrefabType.Prefab && prefabType != PrefabType.ModelPrefab); -#endif - } + #endif + } public static GameObject GetPrefabAsset(GameObject gameObject) { -#if UNITY_2018_3_OR_NEWER + #if UNITY_2018_3_OR_NEWER if (AreInPrefabMode()) { -#if UNITY_2021_2_OR_NEWER - var prefabStage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); -#else + #if !UNITY_2021_2_OR_NEWER var prefabStage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); -#endif + #else + var prefabStage = UnityEditor.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); + #endif if (prefabStage.IsPartOfPrefabContents(gameObject)) -#if UNITY_2020_1_OR_NEWER + #if UNITY_2020_1_OR_NEWER return (GameObject)AssetDatabase.LoadMainAssetAtPath(prefabStage.assetPath); -#else + #else return (GameObject)AssetDatabase.LoadMainAssetAtPath(prefabStage.prefabAssetPath); -#endif + #endif } -#endif + #endif if (!IsPrefabInstance(gameObject)) return null; -#if UNITY_2018_3_OR_NEWER + #if UNITY_2018_3_OR_NEWER return (GameObject)AssetDatabase.LoadMainAssetAtPath(PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(gameObject)); -#else + #else return (GameObject)PrefabUtility.GetPrefabParent(gameObject); -#endif + #endif } public static GameObject GetOutermostPrefabInstanceRoot(GameObject gameObject) - { - if (!IsPrefabInstance(gameObject)) - return null; -#if UNITY_2018_3_OR_NEWER - return PrefabUtility.GetOutermostPrefabInstanceRoot(gameObject); -#else + { + if (!IsPrefabInstance(gameObject)) + return null; + #if UNITY_2018_3_OR_NEWER + return PrefabUtility.GetOutermostPrefabInstanceRoot(gameObject); + #else return PrefabUtility.FindPrefabRoot(gameObject); -#endif - } - - public static GameObject Instantiate(GameObject originalGameObject, bool copy = false) - { -#if UNITY_2018_3_OR_NEWER - var prefabInstanceType = PrefabUtility.GetPrefabInstanceStatus(originalGameObject); - if (prefabInstanceType != PrefabInstanceStatus.NotAPrefab && !copy) - { - var corrObj = GetCorrespondingObjectFromSource(originalGameObject); - var obj = PrefabUtility.InstantiatePrefab(corrObj); - var result = obj as GameObject; - return result; - } - - var prefabAssetType = PrefabUtility.GetPrefabAssetType(originalGameObject); - if (prefabAssetType != PrefabAssetType.NotAPrefab && !copy) - { - var obj = PrefabUtility.InstantiatePrefab(originalGameObject); - var result = obj as GameObject; - return result; - } - - var inst = UnityEngine.Object.Instantiate(originalGameObject); - return inst; -#else + #endif + } + + public static GameObject Instantiate(GameObject originalGameObject, bool copy = false) + { + #if UNITY_2018_3_OR_NEWER + var prefabInstanceType = PrefabUtility.GetPrefabInstanceStatus(originalGameObject); + if (prefabInstanceType != PrefabInstanceStatus.NotAPrefab && !copy) + { + var corrObj = GetCorrespondingObjectFromSource(originalGameObject); + var obj = PrefabUtility.InstantiatePrefab(corrObj); + var result = obj as GameObject; + return result; + } + + var prefabAssetType = PrefabUtility.GetPrefabAssetType(originalGameObject); + if (prefabAssetType != PrefabAssetType.NotAPrefab && !copy) + { + var obj = PrefabUtility.InstantiatePrefab(originalGameObject); + var result = obj as GameObject; + return result; + } + + var inst = UnityEngine.Object.Instantiate(originalGameObject); + return inst; + #else var prefabType = PrefabUtility.GetPrefabType(originalGameObject); if (prefabType == PrefabType.None || copy) return UnityEngine.Object.Instantiate(originalGameObject); @@ -196,8 +196,8 @@ public static GameObject Instantiate(GameObject originalGameObject, bool copy = else // PrefabInstance return PrefabUtility.InstantiatePrefab(GetCorrespondingObjectFromSource(originalGameObject)) as GameObject; -#endif - } + #endif + } internal static bool IsPartOfAsset(Mesh sharedMesh) { diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeManager.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeManager.cs index ff8d011..50be54c 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeManager.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeManager.cs @@ -517,7 +517,7 @@ public static void OnSceneGUI(SceneView sceneView) if (RealtimeCSG.CSGSettings.EnableRealtimeCSG) { // handle the tool - var sceneSize = sceneView.position.size; + var sceneSize = sceneView.position.size; var sceneRect = new Rect(0, 0, sceneSize.x, sceneSize.y - ((CSG_GUIStyleUtility.BottomToolBarHeight + 4) + 17)); // This helps prevent weird issues with overlapping sceneviews + avoid some performance issues with multiple sceneviews open diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeSelection.GUI.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeSelection.GUI.cs index e945c75..4be2382 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeSelection.GUI.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeSelection.GUI.cs @@ -51,7 +51,7 @@ static void HandleSceneGUI(int id) if (!SceneDragToolManager.IsDraggingObjectInScene) OnEditModeSelectionSceneGUI(); - var viewRect = new Rect(4, 0, sceneView.position.width, sceneView.position.height - (CSG_GUIStyleUtility.BottomToolBarHeight + 4)); + var viewRect = new Rect(4, 0, sceneView.rootVisualElement.contentRect.width, sceneView.rootVisualElement.contentRect.height - (CSG_GUIStyleUtility.BottomToolBarHeight + 4)); GUILayout.BeginArea(viewRect); if (EditModeManager.ActiveTool != null) diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeToolWindow.Editor.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeToolWindow.Editor.cs index 8103908..cb89f53 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeToolWindow.Editor.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModeToolWindow.Editor.cs @@ -9,11 +9,12 @@ public class EditModeToolWindowEditor : Editor public Bounds OnGetFrameBounds() { return RealtimeCSG.BoundsUtilities.OnGetFrameBounds(RealtimeCSG.EditModeManager.FilteredSelection); } public override void OnInspectorGUI() { - if (EditorApplication.isPlayingOrWillChangePlaymode) - { - Selection.activeObject = null; - return; - } + if( EditorApplication.isPlayingOrWillChangePlaymode ) + { + Selection.activeObject = null; + + return; + } RealtimeCSG.EditModeSelectionGUI.OnInspectorGUI(this, this.targets); } } \ No newline at end of file diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUI.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUI.cs index 1d2ceb1..312a397 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUI.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUI.cs @@ -1,250 +1,274 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; +using UnityEditor; using UnityEngine; -using UnityEngine.SceneManagement; + namespace RealtimeCSG { - internal sealed partial class GeneratorCylinderGUI - { - static bool SettingsToggle(bool value, GUIContent content, GUILayoutOption sceneWidth, bool isSceneGUI) - { - if (isSceneGUI) - return EditorGUILayout.ToggleLeft(content, value, sceneWidth); - else - return EditorGUILayout.Toggle(content, value); - } - - static float SettingsSlider(float value, float minValue, float maxValue, GUIContent content, bool isSceneGUI) - { - if (isSceneGUI) - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.Slider(value, minValue, maxValue, width120); - GUILayout.EndHorizontal(); - return result; - } else - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.Slider(value, minValue, maxValue); - GUILayout.EndHorizontal(); - return result; - } - } - - static int IntSettingsSlider(int value, int minValue, int maxValue, GUIContent content, bool isSceneGUI) - { - if (isSceneGUI) - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.IntSlider(value, minValue, maxValue, width120); - GUILayout.EndHorizontal(); - return result; - } else - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.IntSlider(value, minValue, maxValue); - GUILayout.EndHorizontal(); - return result; - } - } - - static void CylinderSettingsGUI(GeneratorCylinder generator, bool isSceneGUI) - { - if (isSceneGUI) - GUILayout.BeginHorizontal(GUILayout.MinWidth(0)); - { - if (isSceneGUI) - GUILayout.BeginVertical(width110); - { - generator.CircleSmoothShading = SettingsToggle(generator.CircleSmoothShading, SmoothShadingContent, width110, isSceneGUI); - TooltipUtility.SetToolTip(SmoothShadingTooltip); - generator.CircleDistanceToSide = SettingsToggle(generator.CircleDistanceToSide, AlignToSideContent, width110, isSceneGUI); - TooltipUtility.SetToolTip(AlignToSideTooltip); - } - if (isSceneGUI) - { - GUILayout.EndVertical(); - GUILayout.BeginVertical(width80); - } - { - generator.CircleSingleSurfaceEnds = !SettingsToggle(!generator.CircleSingleSurfaceEnds, RadialCapsContent, width80, isSceneGUI); - TooltipUtility.SetToolTip(RadialCapsTooltip); - generator.CircleRecenter = SettingsToggle(generator.CircleRecenter, FitShapeContent, width80, isSceneGUI); - TooltipUtility.SetToolTip(FitShapeTooltip); - } - if (isSceneGUI) - GUILayout.EndVertical(); - } - if (isSceneGUI) - GUILayout.EndHorizontal(); - } - - static void OnGUIContents(GeneratorCylinder generator, bool isSceneGUI) - { - //GUILayout.BeginVertical(GUIStyleUtility.ContentEmpty); - //{ - //bool enabled = generator.HaveBrushes; - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - { - /* - EditorGUI.BeginDisabledGroup(!enabled); - { - if (isSceneGUI) - GUILayout.BeginVertical(GUI.skin.box, width100); - else - GUILayout.BeginVertical(GUIStyle.none); - { - bool mixedValues = !enabled; - CSGOperationType operation = generator.CurrentCSGOperationType; - EditorGUI.BeginChangeCheck(); - operation = CSG_EditorGUIUtility.ChooseOperation(operation, mixedValues); - if (EditorGUI.EndChangeCheck()) - { - generator.CurrentCSGOperationType = operation; - } - } - GUILayout.EndVertical(); - } - EditorGUI.EndDisabledGroup(); - */ - if (isSceneGUI) - CylinderSettingsGUI(generator, isSceneGUI); - } - GUILayout.EndHorizontal(); - - GUILayout.Space(5); - - GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty); - { - var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit; - var nextUnit = Units.CycleToNextUnit(distanceUnit); - var unitText = Units.GetUnitGUIContent(distanceUnit); - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - { - GUILayout.Label(HeightContent, width65); - if (isSceneGUI) - TooltipUtility.SetToolTip(HeightTooltip); - var height = generator.HaveHeight ? generator.Height : GeometryUtility.CleanLength(generator.DefaultHeight); - EditorGUI.BeginChangeCheck(); - { - if (!isSceneGUI) - height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height))); - else - height = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, height), width65)); - } - if (EditorGUI.EndChangeCheck()) - { - if (generator.HaveHeight) - generator.Height = height; - else - generator.DefaultHeight = height; - } - if (GUILayout.Button(unitText, EditorStyles.miniLabel, width20)) - { - distanceUnit = nextUnit; - RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit; - RealtimeCSG.CSGSettings.UpdateSnapSettings(); - RealtimeCSG.CSGSettings.Save(); - CSG_EditorGUIUtility.RepaintAll(); - } - } - //if (!isSceneGUI) - { - GUILayout.EndHorizontal(); - TooltipUtility.SetToolTip(HeightTooltip); - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - } - //else - //{ - // GUILayout.Space(12); - //} - { - EditorGUI.BeginDisabledGroup(!generator.CanCommit); - { - GUILayout.Label(RadiusContent, width65); - if (isSceneGUI) - TooltipUtility.SetToolTip(RadiusTooltip); - var radius = generator.RadiusA; - EditorGUI.BeginChangeCheck(); - { - if (!isSceneGUI) - radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius))); - else - radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius), width65)); - } - if (EditorGUI.EndChangeCheck()) - { - generator.RadiusA = radius; - } - if (GUILayout.Button(unitText, EditorStyles.miniLabel, width20)) - { - distanceUnit = nextUnit; - RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit; - RealtimeCSG.CSGSettings.UpdateSnapSettings(); - RealtimeCSG.CSGSettings.Save(); - CSG_EditorGUIUtility.RepaintAll(); - } - } - EditorGUI.EndDisabledGroup(); - } - GUILayout.EndHorizontal(); - if (!isSceneGUI) - TooltipUtility.SetToolTip(RadiusTooltip); - } - GUILayout.EndVertical(); - - { - generator.CircleSides = IntSettingsSlider(generator.CircleSides, 3, RealtimeCSG.CSGSettings.MaxCircleSides, SidesContent, isSceneGUI); - TooltipUtility.SetToolTip(SidesTooltip); - } - { - generator.CircleOffset = SettingsSlider(generator.CircleOffset, 0, 360, OffsetContent, isSceneGUI); - TooltipUtility.SetToolTip(OffsetTooltip); - } - - - - if (!isSceneGUI) - { - GUILayout.Space(5); - - CylinderSettingsGUI(generator, isSceneGUI); - - //GUILayout.Space(10); - } /*else - { - GUILayout.Space(10); - }*/ - /* - EditorGUI.BeginDisabledGroup(!generator.CanCommit); - { - GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty); - { - if (GUILayout.Button(CommitContent)) { generator.DoCommit(); } - TooltipUtility.SetToolTip(CommitTooltip); - if (GUILayout.Button(CancelContent)) { generator.DoCancel(); } - TooltipUtility.SetToolTip(CancelTooltip); - } - GUILayout.EndHorizontal(); - } - EditorGUI.EndDisabledGroup(); - */ - //} - //GUILayout.EndVertical(); - } - - public static bool OnShowGUI(GeneratorCylinder generator, bool isSceneGUI) - { - CSG_GUIStyleUtility.InitStyles(); - OnGUIContents(generator, isSceneGUI); - return true; - } - } + internal sealed partial class GeneratorCylinderGUI + { + static bool SettingsToggle( bool value, GUIContent content, GUILayoutOption sceneWidth, bool isSceneGUI ) + { + if( isSceneGUI ) + return EditorGUILayout.ToggleLeft( content, value, sceneWidth ); + else + return EditorGUILayout.Toggle( content, value ); + } + + static float FloatSettingsControl( float value, float minValue, float maxValue, GUIContent content, bool isSceneGUI ) + { + if( isSceneGUI ) + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + GUI.enabled = false; + + value = EditorGUILayout.FloatField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + else + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + + GUI.enabled = false; + + value = EditorGUILayout.FloatField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + } + + static int IntSettingsControl( int value, int minValue, int maxValue, GUIContent content, bool isSceneGUI ) + { + if( isSceneGUI ) + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + + GUI.enabled = false; + + value = EditorGUILayout.IntField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + else + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + + GUI.enabled = false; + + value = EditorGUILayout.IntField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + } + + static void CylinderSettingsGUI( GeneratorCylinder generator, bool isSceneGUI ) + { + if( isSceneGUI ) + GUILayout.BeginHorizontal( GUILayout.MinWidth( 0 ) ); + + if( isSceneGUI ) + GUILayout.BeginVertical( width110 ); + + generator.CircleSmoothShading = SettingsToggle( generator.CircleSmoothShading, SmoothShadingContent, width110, isSceneGUI ); + TooltipUtility.SetToolTip( SmoothShadingTooltip ); + generator.CircleDistanceToSide = SettingsToggle( generator.CircleDistanceToSide, AlignToSideContent, width110, isSceneGUI ); + TooltipUtility.SetToolTip( AlignToSideTooltip ); + + if( isSceneGUI ) + { + GUILayout.EndVertical(); + GUILayout.BeginVertical( width80 ); + } + + generator.CircleSingleSurfaceEnds = !SettingsToggle( !generator.CircleSingleSurfaceEnds, RadialCapsContent, width80, isSceneGUI ); + TooltipUtility.SetToolTip( RadialCapsTooltip ); + generator.CircleRecenter = SettingsToggle( generator.CircleRecenter, FitShapeContent, width80, isSceneGUI ); + TooltipUtility.SetToolTip( FitShapeTooltip ); + + if( isSceneGUI ) + GUILayout.EndVertical(); + + if( isSceneGUI ) + GUILayout.EndHorizontal(); + } + + static void OnGUIContents( GeneratorCylinder generator, bool isSceneGUI ) + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + { + if( isSceneGUI ) + CylinderSettingsGUI( generator, isSceneGUI ); + } + GUILayout.EndHorizontal(); + + GUILayout.Space( 5 ); + + GUILayout.BeginVertical( CSG_GUIStyleUtility.ContentEmpty ); + { + var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit; + var nextUnit = Units.CycleToNextUnit( distanceUnit ); + var unitText = Units.GetUnitGUIContent( distanceUnit ); + + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + { + GUILayout.Label( HeightContent, width65 ); + + if( isSceneGUI ) + TooltipUtility.SetToolTip( HeightTooltip ); + + var height = generator.HaveHeight ? generator.Height : GeometryUtility.CleanLength( generator.DefaultHeight ); + EditorGUI.BeginChangeCheck(); + { + if( !isSceneGUI ) + height = Units.DistanceUnitToUnity( distanceUnit, EditorGUILayout.DoubleField( Units.UnityToDistanceUnit( distanceUnit, height ) ) ); + else + height = Units.DistanceUnitToUnity( distanceUnit, EditorGUILayout.DoubleField( Units.UnityToDistanceUnit( distanceUnit, height ), width65 ) ); + } + + if( EditorGUI.EndChangeCheck() ) + { + if( generator.HaveHeight ) + generator.Height = height; + else + generator.DefaultHeight = height; + } + + if( GUILayout.Button( unitText, EditorStyles.miniLabel, width25 ) ) + { + distanceUnit = nextUnit; + RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit; + RealtimeCSG.CSGSettings.UpdateSnapSettings(); + RealtimeCSG.CSGSettings.Save(); + CSG_EditorGUIUtility.RepaintAll(); + } + } + GUILayout.EndHorizontal(); + + TooltipUtility.SetToolTip( HeightTooltip ); + + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + { + EditorGUI.BeginDisabledGroup( !generator.CanCommit ); + { + GUILayout.Label( RadiusContent, width65 ); + + if( isSceneGUI ) + TooltipUtility.SetToolTip( RadiusTooltip ); + + var radius = generator.RadiusA; + EditorGUI.BeginChangeCheck(); + { + if( !isSceneGUI ) + radius = Units.DistanceUnitToUnity( distanceUnit, EditorGUILayout.DoubleField( Units.UnityToDistanceUnit( distanceUnit, radius ) ) ); + else + radius = Units.DistanceUnitToUnity( distanceUnit, EditorGUILayout.DoubleField( Units.UnityToDistanceUnit( distanceUnit, radius ), width65 ) ); + } + + if( EditorGUI.EndChangeCheck() ) + { + generator.RadiusA = radius; + } + + if( GUILayout.Button( unitText, EditorStyles.miniLabel, width25 ) ) + { + distanceUnit = nextUnit; + RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit; + RealtimeCSG.CSGSettings.UpdateSnapSettings(); + RealtimeCSG.CSGSettings.Save(); + CSG_EditorGUIUtility.RepaintAll(); + } + } + EditorGUI.EndDisabledGroup(); + } + GUILayout.EndHorizontal(); + + if( !isSceneGUI ) + TooltipUtility.SetToolTip( RadiusTooltip ); + } + + GUILayout.EndVertical(); + { + generator.CircleSides = IntSettingsControl + ( + generator.CircleSides, + 3, + RealtimeCSG.CSGSettings.MaxCircleSides, + SidesContent, + isSceneGUI + ); + + TooltipUtility.SetToolTip( SidesTooltip ); + } + generator.CircleOffset = FloatSettingsControl + ( + generator.CircleOffset, + 0, + 360, + OffsetContent, + isSceneGUI + ); + + TooltipUtility.SetToolTip( OffsetTooltip ); + + + if( !isSceneGUI ) + { + GUILayout.Space( 5 ); + + CylinderSettingsGUI( generator, isSceneGUI ); + } + } + + public static bool OnShowGUI( GeneratorCylinder generator, bool isSceneGUI ) + { + CSG_GUIStyleUtility.InitStyles(); + OnGUIContents( generator, isSceneGUI ); + + return true; + } + } } diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUIContents.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUIContents.cs index 3e167dc..0907def 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUIContents.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Cylinder.GUIContents.cs @@ -1,35 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using UnityEngine.SceneManagement; +using UnityEngine; + namespace RealtimeCSG { - internal sealed partial class GeneratorCylinderGUI - { - private static readonly GUIContent SmoothShadingContent = new GUIContent("Smooth shading"); - private static readonly ToolTip SmoothShadingTooltip = new ToolTip("Smooth shading", "Toggle if you want the sides of the cylinder have smooth lighting or have a faceted look."); - private static readonly GUIContent RadialCapsContent = new GUIContent("Radial caps"); - private static readonly ToolTip RadialCapsTooltip = new ToolTip("Radial caps", "Toggle if you want the top and bottom of the cylinder be a single polygon, or have a triangle per side."); - private static readonly GUIContent AlignToSideContent = new GUIContent("Start mid side"); - private static readonly ToolTip AlignToSideTooltip = new ToolTip("Start in the middle of a side", "Toggle if you want the cylinder to begin in the center of a side, or at a point."); - private static readonly GUIContent FitShapeContent = new GUIContent("Fit shape"); - private static readonly ToolTip FitShapeTooltip = new ToolTip("Fit shape", "Toggle if you want the cylinder to be fitted to the square that encapsulates the full circle that's defined by its radius. This makes the shapes more predictable when they have only a few sides, but it may change its shape slightly."); - private static readonly GUIContent OffsetContent = new GUIContent("Angle"); - private static readonly ToolTip OffsetTooltip = new ToolTip("Offset angle", "Set the offset angle at which the cylinder starts."); - private static readonly GUIContent SidesContent = new GUIContent("Sides"); - private static readonly ToolTip SidesTooltip = new ToolTip("Number of sides", "Set the number of sides the cylinder has when generated."); - private static readonly GUIContent HeightContent = new GUIContent("Height"); - private static readonly ToolTip HeightTooltip = new ToolTip("Height", "Set the height of the cylinder."); - private static readonly GUIContent RadiusContent = new GUIContent("Radius"); - private static readonly ToolTip RadiusTooltip = new ToolTip("Radius", "Set the radius of the cylinder. The radius is half of the width of a cylinder."); - - private static readonly GUILayoutOption width20 = GUILayout.Width(25); - private static readonly GUILayoutOption width65 = GUILayout.Width(65); - private static readonly GUILayoutOption width80 = GUILayout.Width(80); - private static readonly GUILayoutOption width110 = GUILayout.Width(110); - private static readonly GUILayoutOption width120 = GUILayout.Width(120); - } + internal sealed partial class GeneratorCylinderGUI + { + private static readonly GUIContent SmoothShadingContent = new GUIContent( "Smooth shading" ); + private static readonly ToolTip SmoothShadingTooltip = new ToolTip( "Smooth shading", "Toggle if you want the sides of the cylinder have smooth lighting or have a faceted look." ); + private static readonly GUIContent RadialCapsContent = new GUIContent( "Radial caps" ); + private static readonly ToolTip RadialCapsTooltip = new ToolTip( "Radial caps", "Toggle if you want the top and bottom of the cylinder be a single polygon, or have a triangle per side." ); + private static readonly GUIContent AlignToSideContent = new GUIContent( "Start mid side" ); + private static readonly ToolTip AlignToSideTooltip = new ToolTip( "Start in the middle of a side", "Toggle if you want the cylinder to begin in the center of a side, or at a point." ); + private static readonly GUIContent FitShapeContent = new GUIContent( "Fit shape" ); + private static readonly ToolTip FitShapeTooltip = new ToolTip( "Fit shape", "Toggle if you want the cylinder to be fitted to the square that encapsulates the full circle that's defined by its radius. This makes the shapes more predictable when they have only a few sides, but it may change its shape slightly." ); + private static readonly GUIContent OffsetContent = new GUIContent( "Angle" ); + private static readonly ToolTip OffsetTooltip = new ToolTip( "Offset angle", "Set the offset angle at which the cylinder starts." ); + private static readonly GUIContent SidesContent = new GUIContent( "Sides" ); + private static readonly ToolTip SidesTooltip = new ToolTip( "Number of sides", "Set the number of sides the cylinder has when generated." ); + private static readonly GUIContent HeightContent = new GUIContent( "Height" ); + private static readonly ToolTip HeightTooltip = new ToolTip( "Height", "Set the height of the cylinder." ); + private static readonly GUIContent RadiusContent = new GUIContent( "Radius" ); + private static readonly ToolTip RadiusTooltip = new ToolTip( "Radius", "Set the radius of the cylinder. The radius is half of the width of a cylinder." ); + + private static readonly GUILayoutOption width25 = GUILayout.Width( 25 ); + private static readonly GUILayoutOption width65 = GUILayout.Width( 65 ); + private static readonly GUILayoutOption width80 = GUILayout.Width( 80 ); + private static readonly GUILayoutOption width110 = GUILayout.Width( 110 ); + } } diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUI.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUI.cs index 3072cb6..4c4c406 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUI.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUI.cs @@ -1,192 +1,221 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; +using UnityEditor; using UnityEngine; -using UnityEngine.SceneManagement; + namespace RealtimeCSG { - internal sealed partial class GeneratorSphereGUI - { - static bool SettingsToggle(bool value, GUIContent content, bool isSceneGUI) - { - if (isSceneGUI) - return EditorGUILayout.ToggleLeft(content, value, width120); - else - return EditorGUILayout.Toggle(content, value); - } - - static float SettingsSlider(float value, float minValue, float maxValue, GUIContent content, bool isSceneGUI) - { - if (isSceneGUI) - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.Slider(value, minValue, maxValue, width120); - GUILayout.EndHorizontal(); - return result; - } else - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.Slider(value, minValue, maxValue); - GUILayout.EndHorizontal(); - return result; - } - } - - static int IntSettingsSlider(int value, int minValue, int maxValue, GUIContent content, bool isSceneGUI) - { - if (isSceneGUI) - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.IntSlider(value, minValue, maxValue, width120); - GUILayout.EndHorizontal(); - return result; - } else - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - GUILayout.Label(content, width65); - var result = EditorGUILayout.IntSlider(value, minValue, maxValue); - GUILayout.EndHorizontal(); - return result; - } - } - - static void SphereSettingsGUI(GeneratorSphere generator, bool isSceneGUI) - { - GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty); - { - generator.SphereSmoothShading = SettingsToggle(generator.SphereSmoothShading, SmoothShadingContent, isSceneGUI); - TooltipUtility.SetToolTip(SmoothShadingTooltip); - generator.IsHemiSphere = SettingsToggle(generator.IsHemiSphere, HemiSphereContent, isSceneGUI); - TooltipUtility.SetToolTip(HemiSphereTooltip); - } - GUILayout.EndVertical(); - } - - static void OnGUIContents(GeneratorSphere generator, bool isSceneGUI) - { - var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit; - var nextUnit = Units.CycleToNextUnit(distanceUnit); - var unitText = Units.GetUnitGUIContent(distanceUnit); - //GUILayout.BeginVertical(GUIStyleUtility.ContentEmpty); - //{ - //bool enabled = generator.HaveBrushes; - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - { - /* - EditorGUI.BeginDisabledGroup(!enabled); - { - if (isSceneGUI) - GUILayout.BeginVertical(GUI.skin.box, width100); - else - GUILayout.BeginVertical(GUIStyle.none); - { - bool mixedValues = !enabled; - CSGOperationType operation = generator.CurrentCSGOperationType; - EditorGUI.BeginChangeCheck(); - operation = CSG_EditorGUIUtility.ChooseOperation(operation, mixedValues); - if (EditorGUI.EndChangeCheck()) - { - generator.CurrentCSGOperationType = operation; - } - } - GUILayout.EndVertical(); - } - EditorGUI.EndDisabledGroup(); - */ - if (isSceneGUI) - SphereSettingsGUI(generator, isSceneGUI); - } - GUILayout.EndHorizontal(); - - GUILayout.Space(5); - - GUILayout.BeginVertical(CSG_GUIStyleUtility.ContentEmpty); - { - GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); - { - EditorGUI.BeginDisabledGroup(!generator.CanCommit); - { - GUILayout.Label(RadiusContent, width65); - if (isSceneGUI) - TooltipUtility.SetToolTip(RadiusTooltip); - var radius = generator.SphereRadius; - EditorGUI.BeginChangeCheck(); - { - if (!isSceneGUI) - radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius))); - else - radius = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, radius), width65)); - } - if (EditorGUI.EndChangeCheck()) - { - generator.SphereRadius = radius; - } - if (GUILayout.Button(unitText, EditorStyles.miniLabel, width25)) - { - distanceUnit = nextUnit; - RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit; - RealtimeCSG.CSGSettings.UpdateSnapSettings(); - RealtimeCSG.CSGSettings.Save(); - CSG_EditorGUIUtility.RepaintAll(); - } - } - EditorGUI.EndDisabledGroup(); - } - GUILayout.EndHorizontal(); - if (!isSceneGUI) - TooltipUtility.SetToolTip(RadiusTooltip); - - { - generator.SphereSplits = IntSettingsSlider(generator.SphereSplits, 1, RealtimeCSG.CSGSettings.MaxSphereSplits, SplitsContent, isSceneGUI); - TooltipUtility.SetToolTip(SplitsTooltip); - } - { - generator.SphereOffset = SettingsSlider(generator.SphereOffset, 0, 360, OffsetContent, isSceneGUI); - TooltipUtility.SetToolTip(OffsetTooltip); - } - - } - GUILayout.EndVertical(); - - if (!isSceneGUI) - { - GUILayout.Space(5); - - SphereSettingsGUI(generator, isSceneGUI); - - //GUILayout.Space(10); - }/* else - { - GUILayout.Space(10); - }*/ - /* - EditorGUI.BeginDisabledGroup(!generator.CanCommit); - { - GUILayout.BeginHorizontal(GUIStyleUtility.ContentEmpty); - { - if (GUILayout.Button(CommitContent)) { generator.DoCommit(); } - TooltipUtility.SetToolTip(CommitTooltip); - if (GUILayout.Button(CancelContent)) { generator.DoCancel(); } - TooltipUtility.SetToolTip(CancelTooltip); - } - GUILayout.EndHorizontal(); - } - EditorGUI.EndDisabledGroup(); - */ - //} - //GUILayout.EndVertical(); - } - - public static bool OnShowGUI(GeneratorSphere generator, bool isSceneGUI) - { - CSG_GUIStyleUtility.InitStyles(); - OnGUIContents(generator, isSceneGUI); - return true; - } - } + internal sealed partial class GeneratorSphereGUI + { + static bool SettingsToggle( bool value, GUIContent content, bool isSceneGUI ) + { + if( isSceneGUI ) + return EditorGUILayout.ToggleLeft( content, value, width120 ); + else + return EditorGUILayout.Toggle( content, value ); + } + + + static float FloatSettingsControl( float value, float minValue, float maxValue, GUIContent content, bool isSceneGUI ) + { + if( isSceneGUI ) + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + GUI.enabled = false; + + value = EditorGUILayout.FloatField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + else + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + + GUI.enabled = false; + + value = EditorGUILayout.FloatField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + } + + static int IntSettingsControl( int value, int minValue, int maxValue, GUIContent content, bool isSceneGUI ) + { + if( isSceneGUI ) + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + + GUI.enabled = false; + + value = EditorGUILayout.IntField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + else + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + GUILayout.Label( content, width65 ); + + GUI.enabled = false; + + value = EditorGUILayout.IntField( Mathf.Clamp( value, minValue, maxValue ) ); + + GUI.enabled = true; + + if( GUILayout.Button( "-", "buttonleft", width25 ) ) + value--; + + if( GUILayout.Button( "+", "buttonright", width25 ) ) + value++; + + GUILayout.EndHorizontal(); + + return value; + } + } + + static void SphereSettingsGUI( GeneratorSphere generator, bool isSceneGUI ) + { + GUILayout.BeginVertical( CSG_GUIStyleUtility.ContentEmpty ); + { + generator.SphereSmoothShading = SettingsToggle( generator.SphereSmoothShading, SmoothShadingContent, isSceneGUI ); + TooltipUtility.SetToolTip( SmoothShadingTooltip ); + generator.IsHemiSphere = SettingsToggle( generator.IsHemiSphere, HemiSphereContent, isSceneGUI ); + TooltipUtility.SetToolTip( HemiSphereTooltip ); + } + GUILayout.EndVertical(); + } + + static void OnGUIContents( GeneratorSphere generator, bool isSceneGUI ) + { + var distanceUnit = RealtimeCSG.CSGSettings.DistanceUnit; + var nextUnit = Units.CycleToNextUnit( distanceUnit ); + var unitText = Units.GetUnitGUIContent( distanceUnit ); + + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + { + if( isSceneGUI ) + SphereSettingsGUI( generator, isSceneGUI ); + } + GUILayout.EndHorizontal(); + + GUILayout.Space( 5 ); + + GUILayout.BeginVertical( CSG_GUIStyleUtility.ContentEmpty ); + { + GUILayout.BeginHorizontal( CSG_GUIStyleUtility.ContentEmpty ); + { + EditorGUI.BeginDisabledGroup( !generator.CanCommit ); + { + GUILayout.Label( RadiusContent, width65 ); + + if( isSceneGUI ) + TooltipUtility.SetToolTip( RadiusTooltip ); + + var radius = generator.SphereRadius; + EditorGUI.BeginChangeCheck(); + { + if( !isSceneGUI ) + radius = Units.DistanceUnitToUnity( distanceUnit, EditorGUILayout.DoubleField( Units.UnityToDistanceUnit( distanceUnit, radius ) ) ); + else + radius = Units.DistanceUnitToUnity( distanceUnit, EditorGUILayout.DoubleField( Units.UnityToDistanceUnit( distanceUnit, radius ), width65 ) ); + } + + if( EditorGUI.EndChangeCheck() ) + { + generator.SphereRadius = radius; + } + + if( GUILayout.Button( unitText, EditorStyles.miniLabel, width25 ) ) + { + distanceUnit = nextUnit; + RealtimeCSG.CSGSettings.DistanceUnit = distanceUnit; + RealtimeCSG.CSGSettings.UpdateSnapSettings(); + RealtimeCSG.CSGSettings.Save(); + CSG_EditorGUIUtility.RepaintAll(); + } + } + EditorGUI.EndDisabledGroup(); + } + + GUILayout.EndHorizontal(); + + if( !isSceneGUI ) + TooltipUtility.SetToolTip( RadiusTooltip ); + + + generator.SphereSplits = IntSettingsControl + ( + generator.SphereSplits, + 1, + RealtimeCSG.CSGSettings.MaxSphereSplits, + SplitsContent, + isSceneGUI + ); + + TooltipUtility.SetToolTip( SplitsTooltip ); + + generator.SphereOffset = FloatSettingsControl + ( + generator.SphereOffset, + 0, + 360, + OffsetContent, + isSceneGUI + ); + + TooltipUtility.SetToolTip( OffsetTooltip ); + + } + + GUILayout.EndVertical(); + + if( !isSceneGUI ) + { + GUILayout.Space( 5 ); + + SphereSettingsGUI( generator, isSceneGUI ); + } + } + + public static bool OnShowGUI( GeneratorSphere generator, bool isSceneGUI ) + { + CSG_GUIStyleUtility.InitStyles(); + OnGUIContents( generator, isSceneGUI ); + + return true; + } + } } diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUIContents.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUIContents.cs index e45fbf0..aecc7a8 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUIContents.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.GUIContents.cs @@ -1,27 +1,23 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine; -using UnityEngine.SceneManagement; +using UnityEngine; + namespace RealtimeCSG { - internal sealed partial class GeneratorSphereGUI - { - private static readonly GUIContent SmoothShadingContent = new GUIContent("Smooth shading"); - private static readonly ToolTip SmoothShadingTooltip = new ToolTip("Smooth shading", "Toggle if you want the sides of the sphere have smooth lighting or have a faceted look."); - private static readonly GUIContent HemiSphereContent = new GUIContent("Hemisphere"); - private static readonly ToolTip HemiSphereTooltip = new ToolTip("Hemisphere", "When toggled, create a hemisphere instead of a sphere."); - private static readonly GUIContent OffsetContent = new GUIContent("Offset"); - private static readonly ToolTip OffsetTooltip = new ToolTip("Offset angle", "Set the offset angle at which the cylinder starts."); - private static readonly GUIContent SplitsContent = new GUIContent("Splits"); - private static readonly ToolTip SplitsTooltip = new ToolTip("Number of splits", "Set the number of times the sides of the spherical cube to be split."); - private static readonly GUIContent RadiusContent = new GUIContent("Radius"); - private static readonly ToolTip RadiusTooltip = new ToolTip("Radius", "Set the radius of the cylinder. The radius is half of the width of a cylinder."); - - private static readonly GUILayoutOption width25 = GUILayout.Width(25); - private static readonly GUILayoutOption width65 = GUILayout.Width(65); - private static readonly GUILayoutOption width120 = GUILayout.Width(120); - } + internal sealed partial class GeneratorSphereGUI + { + private static readonly GUIContent SmoothShadingContent = new GUIContent( "Smooth shading" ); + private static readonly ToolTip SmoothShadingTooltip = new ToolTip( "Smooth shading", "Toggle if you want the sides of the sphere have smooth lighting or have a faceted look." ); + private static readonly GUIContent HemiSphereContent = new GUIContent( "Hemisphere" ); + private static readonly ToolTip HemiSphereTooltip = new ToolTip( "Hemisphere", "When toggled, create a hemisphere instead of a sphere." ); + private static readonly GUIContent OffsetContent = new GUIContent( "Offset" ); + private static readonly ToolTip OffsetTooltip = new ToolTip( "Offset angle", "Set the offset angle at which the cylinder starts." ); + private static readonly GUIContent SplitsContent = new GUIContent( "Splits" ); + private static readonly ToolTip SplitsTooltip = new ToolTip( "Number of splits", "Set the number of times the sides of the spherical cube to be split." ); + private static readonly GUIContent RadiusContent = new GUIContent( "Radius" ); + private static readonly ToolTip RadiusTooltip = new ToolTip( "Radius", "Set the radius of the cylinder. The radius is half of the width of a cylinder." ); + + private static readonly GUILayoutOption width25 = GUILayout.Width( 25 ); + private static readonly GUILayoutOption width65 = GUILayout.Width( 65 ); + private static readonly GUILayoutOption width120 = GUILayout.Width( 120 ); + } } diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewBottomBarGUI/SceneViewBottomBar.GUI.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewBottomBarGUI/SceneViewBottomBar.GUI.cs index dd5550f..f242f94 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewBottomBarGUI/SceneViewBottomBar.GUI.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewBottomBarGUI/SceneViewBottomBar.GUI.cs @@ -19,18 +19,13 @@ public static void ShowGUI(SceneView sceneView, bool haveOffset = true) CSG_GUIStyleUtility.InitStyles(); if (sceneView != null) { - float height = sceneView.position.height;//Screen.height; - float width = sceneView.position.width;//Screen.width; - Rect bottomBarRect; + float height = sceneView.rootVisualElement.contentRect.height; //Screen.height; + float width = sceneView.rootVisualElement.contentRect.width; //Screen.width; + Rect bottomBarRect; if (haveOffset) { -#if UNITY_2021_2_OR_NEWER - bottomBarRect = new Rect(0, height - (CSG_GUIStyleUtility.BottomToolBarHeight + 27), - width, CSG_GUIStyleUtility.BottomToolBarHeight); -#else bottomBarRect = new Rect(0, height - (CSG_GUIStyleUtility.BottomToolBarHeight + 18), width, CSG_GUIStyleUtility.BottomToolBarHeight); -#endif } else bottomBarRect = new Rect(0, height - (CSG_GUIStyleUtility.BottomToolBarHeight + 1), width, CSG_GUIStyleUtility.BottomToolBarHeight); @@ -87,7 +82,7 @@ static void OnBottomBarGUI(SceneView sceneView, Rect barSize) var updateSurfaces = false; bool wireframeModified = false; - var viewWidth = sceneView.position.width; + var viewWidth = sceneView.rootVisualElement.contentRect.width; float layoutHeight = barSize.height; float layoutX = 6.0f; diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUI.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUI.cs index 6e05dda..e954108 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUI.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUI.cs @@ -1,7 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * -RealtimeCSG.SceneViewInfo.GUI.cs - -License: +License: MIT (TLDR: https://tldrlegal.com/license/mit-license) Author: Daniel Cornelius Description: diff --git a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUIContents.cs b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUIContents.cs index 35fc30c..c10b03a 100644 --- a/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUIContents.cs +++ b/RealtimeCSG/Assets/Plugins/RealtimeCSG/Editor/Scripts/View/GUI/SceneViewInfoGUI/SceneViewInfo.GUIContents.cs @@ -1,26 +1,27 @@ /* * * * * * * * * * * * * * * * * * * * * * -RealtimeCSG.SceneViewInfo.GUIContents.cs - -License: +License: MIT (TLDR: https://tldrlegal.com/license/mit-license) Author: Daniel Cornelius Description: Handles styles for SceneViewInfoGUI * * * * * * * * * * * * * * * * * * * * * */ + using UnityEditor; using UnityEngine; + namespace RealtimeCSG { internal sealed partial class SceneViewInfoGUI { - private static Rect infoGUIRect = new Rect(); - private static Color infoGUITextColor = new Color32( 160, 160, 160, 255 ); - private static GUIStyle infoGUIStyle = null; - private static GUIStyle infoGUIBGStyle = null; - private static float infoGUILabelHeight = 34; - private static Texture2D m_InfoGUIBGTex = null; + private static readonly Color infoGUITextColor = new Color32( 160, 160, 160, 255 ); + + private static Rect infoGUIRect; + private static GUIStyle infoGUIStyle; + private static GUIStyle infoGUIBGStyle; + private const float infoGUILabelHeight = 34; + private static Texture2D m_InfoGUIBGTex; private static Texture2D InfoGUIBGTex { @@ -35,23 +36,29 @@ private static Texture2D InfoGUIBGTex private static void InitStyles( SceneView sceneView ) { - infoGUIRect.x = sceneView.position.width - 116; - infoGUIRect.y = sceneView.position.height - 74; + infoGUIRect.x = sceneView.rootVisualElement.contentRect.width - 116; + infoGUIRect.y = sceneView.rootVisualElement.contentRect.height - 74; infoGUIRect.width = 110; infoGUIRect.height = infoGUILabelHeight; infoGUIStyle = new GUIStyle( "MiniLabel" ) { alignment = TextAnchor.UpperLeft, - normal = new GUIStyleState() { textColor = infoGUITextColor }, - margin = new RectOffset( 0, 0, 0, 0 ), - padding = new RectOffset( 0, 0, 0, 0 ), + normal = new GUIStyleState() + { + textColor = infoGUITextColor + }, + margin = new RectOffset( 0, 0, 0, 0 ), + padding = new RectOffset( 0, 0, 0, 0 ), fontSize = 11 }; infoGUIBGStyle = new GUIStyle( "box" ) { - normal = new GUIStyleState() { background = InfoGUIBGTex } + normal = new GUIStyleState() + { + background = InfoGUIBGTex + } }; } } diff --git a/RealtimeCSG/Packages/manifest.json b/RealtimeCSG/Packages/manifest.json new file mode 100644 index 0000000..34e00ef --- /dev/null +++ b/RealtimeCSG/Packages/manifest.json @@ -0,0 +1,39 @@ +{ + "dependencies": { + "com.unity.ide.rider": "3.0.9", + "com.unity.test-framework": "1.1.29", + "com.unity.timeline": "1.6.3", + "com.unity.ugui": "1.0.0", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/RealtimeCSG/Packages/packages-lock.json b/RealtimeCSG/Packages/packages-lock.json new file mode 100644 index 0000000..429ef36 --- /dev/null +++ b/RealtimeCSG/Packages/packages-lock.json @@ -0,0 +1,306 @@ +{ + "dependencies": { + "com.unity.ext.nunit": { + "version": "1.0.6", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.ide.rider": { + "version": "3.0.9", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6" + }, + "url": "https://packages.unity.com" + }, + "com.unity.test-framework": { + "version": "1.1.29", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.timeline": { + "version": "1.6.3", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.director": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ugui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0" + } + }, + "com.unity.modules.ai": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.androidjni": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.animation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.assetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.audio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.cloth": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.director": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.animation": "1.0.0" + } + }, + "com.unity.modules.imageconversion": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imgui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.jsonserialize": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.particlesystem": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.screencapture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.subsystems": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.terrain": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.terrainphysics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.terrain": "1.0.0" + } + }, + "com.unity.modules.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics2d": "1.0.0" + } + }, + "com.unity.modules.ui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.uielements": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.uielementsnative": "1.0.0" + } + }, + "com.unity.modules.uielementsnative": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.umbra": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unityanalytics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.unitywebrequest": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unitywebrequestassetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestaudio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.audio": "1.0.0" + } + }, + "com.unity.modules.unitywebrequesttexture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestwww": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.vehicles": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.video": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.vr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } + }, + "com.unity.modules.wind": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.xr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.subsystems": "1.0.0" + } + } + } +} diff --git a/RealtimeCSG/ProjectSettings/MemorySettings.asset b/RealtimeCSG/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..5b5face --- /dev/null +++ b/RealtimeCSG/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/RealtimeCSG/ProjectSettings/PackageManagerSettings.asset b/RealtimeCSG/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 0000000..b3df787 --- /dev/null +++ b/RealtimeCSG/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_EnablePreReleasePackages: 1 + m_EnablePackageDependencies: 1 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + oneTimeWarningShown: 1 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_Modified: 0 + m_ErrorMessage: + m_UserModificationsInstanceId: -836 + m_OriginalInstanceId: -838 + m_LoadAssets: 0 diff --git a/RealtimeCSG/ProjectSettings/PresetManager.asset b/RealtimeCSG/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..67a94da --- /dev/null +++ b/RealtimeCSG/ProjectSettings/PresetManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_DefaultPresets: {} diff --git a/RealtimeCSG/ProjectSettings/ProjectSettings.asset b/RealtimeCSG/ProjectSettings/ProjectSettings.asset index d6d2b55aa28682e6249a48d318ccfdd18d6fc83a..85ca196269c53f5be4ac153bdf4c11e085173eca 100644 GIT binary patch literal 70330 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 Hw*~(X`>2*T literal 52530 zcmeIbcYGYx8MZw#rbFnxncjkN1x#I8auLY3u;fCES*_O6Vrh5TUD*~1VF@MFgq9FO zLhm(nLNyRdLhq1}kc1XeDCvau-uHQ)d3MfdCgFRNKfdqx`vz9hUh~W~=bSlh&aC7h zxNpZGcye421ZxGseHnZYCXU{1^n`_DgU>$y{PU(JfMZEN|9tC1uD#^%?_ZuB`@;2; ze{sS+=e)dp5Zo{}2v+58Y`X_R9fy4G-qeGj3IAQOTu{HcDX5PGq)J{*!83?m1MkxW=0pVja^ zs55><6N<0S7y0VIO&Rj#TzWRaG4yisi!+)XjZ6om)7^6c^B$=N5|sB^X?ks;d#fzcz9m4Gq;853D3*Uj~lPc zi>RNc;Jj={>_39KOTX7nCm8qJ=|pmDY`+)4!FI}W+l{bJJ~B8P<#{9au^pkmbXya8 zu4p^j0~D7CujPYiJDOyCq$~eh;bFbn6R#k{cxk8is-OKFw|G0<+cDu$|31dW^SXNW zr372tv!7$bJsIQTL2qs z;uf~Y4&~DY8}Cux7UM@L-#^CBRL=2)Tj;-1dAnf8@pJtya9-~jG5(nHndBMquzsQs zb@g+W#rxw(hjG7tV(f5RIKHrcvK(d`m-2Z})7cs0Ya*EOT`|6!@;NbnuyXX(ZVSs{ zQ2D$FXE~e>&T^O^4OvtR8euao=rb^y33L+;nxBDs6{^OKTsDd!{g zyk&51VS0{MexzXIrzo$)_(jUAF@BTsT8uxad@#meSH3vLKUBUX#+P4F^0|~eBkAY3 zun9P-bTCAYEo?_SD?duG@qLtkHO4!Xe~mmN9?rLWlph_5XT3cVoaO#?@{GijpQ`+r z7(ZWmJ;rZRek?h*@VY#y{2PLezoq=R82_8{U?FjXJ zha6kTi^{(%*myhltT+R(|Ijo!l>< zpBVSk|1fw``X3>8FF*Z{8u!cRG4Q1F`6=Twbou4;GjjLx{f`@$_WK)@&q%N*@ZuJZ z3;$C7q+sJ~tSa$O#rXEhpN??WpK0K{zR!@?>G$VX&jL&O{qlc~+`at%@Ok6XUS`A3 zxEJsW+Y86vZcWdNZxA-R4e)k7w`Tv@{&SU)Y{|#_b z`Tv&Oz5Mcj!?@I+oSyehaBg8gRsrYnZxLqdjU2ab~a>yzlCz=TKFJ^pN5JQLLOmlV%mEq;VIUjNOwcxI~S?&%Z3*_k3(zJjbc$lN8UV7VmpLGcKM>)bn|YhlQL}&U}_2Ts#k|X9OX(`1M-O z;{EiDG%lWBsAu^U&k7drd$=CVL&Ey=v3gcY@o=43;(gC5#w9)LVG_l9$n|4x@qDdj z@xCWqR}Ry&n|i*K;#nibv!-#G$LuCF0-?*gbE1I4S%;Wb<8yff1vr&Xc)3dR0KRug(b5}e)n;Mt&R5U%Cna5Ah z=EnW>Y!Ttn^o%m@r)NuW?uw^pE8~)$Q#3tWo5xSjHpcz*Y#ZUx^lWF`PtW$?+!asH z4#s8NxdQ27f4if3q@Lde&ib&EalgOa**tzd|FUuMJg1&rQaqzA-uLXPoa6Xh)XhI= zI>$sjT;Et_4N3o4^EA2j^EH%@vv}d#DIXu<98dQIXFHleUT3-a*JUF88FK%+>_(15 z$PdJkY)5>*yKyP!d3xSGxD#9050t=J&XbJ$<-DhP{PN**Cms@(&q?avJK~9!&pzgn za=2FG_qBN8k0{?S!dX7Q0%!ST$m=|}Up~$BXUP5XnM{sD;^os~T-wFw>ThLmf`5u} z-#?Wc8~y98DbHn?&S@4e^Z&iEk9@ju|Nf#4T+;8)|Mw?%et-Udfbo&;xzYjZZ)b3w z$N2sk#(n=xa%{Zs;C&YB57Rlz;#c(g^A6)HdH0D2nr9{NK6JLluk782b{b#B^LK$u zIjrjW=a9Q}uIknExyHpG-iOX(aGl5aem)mX@*iX#-+!=isV8%_oDVU-Uk?v8?$?vU z$g#1Wus(<7{1uBI>6OC*a7m{;zYCw&A5QK(%X{UJH7=iv=s`M1BCeak*x26NQ6fvg ziE{jsY49_Y_r&<6%JVVL?aCKM;+d~!!C8NL$?Np{<Qv7^=p5#B$JifnTT>9bh@bkJ<>Bq+F z!gS73UW@UZ^1%q_`1>_*_S=h%`~CJ3aPH##FgjmaYFzSr20Xl8LkzCFc&{EF#rO=l zf4#nH9zVZdGcNwi)PHn}|LZCKW6b0G>&B%%-w8j}$MOrdu%17y{2MX;OXbIrXC$7_ zJwMcR9&hn}y*Tx#;W-vBs6eaao6$-Hr`)wT>HK9>&P?YlHX4>zt@x3$^HD^ zVBF8|jpko2Sbv>Het%@~etvHXqj$erIWw+D<%zA)daGwwlt$?zB{&ywcrA@Vx8f8L)M_sjEP za%{X_(fQjW7VpoK9|f26`}5?-$em{;@4ElgxQuH0TU>7g^ROOG8XXuh~_9D&K z6XbPr|9U-1zl-;;*Hh#;BtGwY+PFM_xmo?sFgU^gta0D}962`nqtBoWBl_ zU;e*zesaHje&syEqy50^#>M}<`hT6`|4oYjx90KZQEwQRdBW@Pk3`YDNk0mR^@{V- zKP!JL!dd@Uz$AzL(%aM+B|GgCd`zihp%;Wn%G%o&e>i=_!|1T;2znaJQ|IN5umuc{iMA849epjBt4_5w< z2-?x5dT+)B6rvG#L zv4!>UJmtX%pWmXqDZ)8_egvHJt`UyA{JQ%55E#pCIdDmjKffJmT;|C?SI_b(o)s+K z_pE4K`t85K!z`^tPloA{db09*(vDUpPq;3t(BtC$>$0l({d%&RaXIg1@bkR<{B?L< zw#VJUSq@(!$Hw$<9yMR%*NE|w@-<`pWaVo)zj)X`Tma7gVQum{x!)hI1D-Sed7ZW+&xoJb z{Wx%5_wC8+_>E~-F<5F(ts((#%j^D|9; z`o}mwx!)egI*;(^I6ls}_?M}Fe2SmH50TU^CYr}j|8B;`|GfHlPx0@O;-6$5-@m7E z@xQJ9y;A&pr}+0VkMG~txcEO(|9&a{Op3qRJidRjaq+LVfz;2I6n|@qe~Nj0|5W4R z-$MPwgYU@n_BB`@4;c{~Gn@Qv5wB{=9j7KYx!(%1!(asJ}PG-@IJG%o)4)n7{Sms9*ln#cE7jEjE-ED~~jtfu&DDgHt8`2NMl#lM;Q zm!$ZYruc`<?F8&GX|7wc=YbpMt&ExyOZe08asQ;K0e?7&2ta*I@H;jwFTm8qS z_>WKVpI{!}f1+{m52^o~DgKjE{3n~o_n%^1{Aa5F)D-_|DgM*V0)6wh}p-uIkqTs+UK=X)uh z^DN%?eBZcuexsiAQ#?Pgc;E9wxbCGfJe5#&{Q#_YgyzjZxxOi6G zNUr;3DW1zM-uGN#Ts#}8=gJh%RTl4it~M^7?bUNlisxF3_dVAc7tciXT%Y2(!Qy?- zjmE{(s-7REcy6+I-*dBZ@pP)^mK4ve7Vmp*GcKNm>bX6|bBD$Io;!_;XGlFiPVwAj z@xJG7Oi#l4!z+x>)G@C4_wTPd zkMQXI`_GMwe}DD=BE|n&ivO49@yFj^85jQo^}n9t|8yT&YdEX>YD7UxhNhr6s&F`Q09piG|EA+g-qhHUcLpj`WnK=lA3Z z>G=cw3F-MGx%2z!`IB);&l`H)_vnwL=M&}c$M`y%NV$Cw<71S67~xF+e&DQ!eZ&--`!BkAWKxETrZj~KsP`9EWPnevZf{CVa7it%@pe;nf< zDgVTA=0VcA+NP48Ph)%w<)6j)IOU(m_!Q-6wr&gk^OZNn_#)*aV*KmMmy7W;m5+?^ z%aku4<98@uA;uq9zG8&4KD-Xj`mhpto#o@NE3ORQlp*)~B|NtT6CUlCRy8jD#;59E z4Lr%eI^z@kUowy1Ue+)!{!KQM^sfn?V*E+v zV`Ka+<>O+Uf7odx&Nx28Sq__lGyM}{d@tn_WBdr^yOBrA=Op#-?&9f`>w7LZ`=33? z>*Rj_GYPyYL+)k5w({&`!C%XxpU=bZx1Ej;hrdfutzb#ni_)9A^N`{%`2 zka*rU<5HggQ2+kmN&W*EpWtsdkDsp@#wB0NkCJ*g6P#O^uQf+WJ()#bC-?Kkzhl&t zA@}ojAUO_+*OS@C<-DUt$$2}$x$(Te!kKm-CA=%fXDOc(<0a*DBb?*xso<>V^T_M; z`{|z#-jtDa^1R{a!w(|IA@TGdY+SC(rK7}u2zZkJP{t?t4>ON{UA|&m{CBH=0eF)C zaKgrQt^Qu{B!3^{6Z{49`2Hh|i~nQw zF9J{U_cK1hKVTl;UobnKhiwDzhYec>#4sAp5(7FKEXd|9^b#% zxcIkI{}S*d|5C;$_=n8n`;Rg%{{7VdRq!PL*BGDRKiWLL|LexZKVSXFfG7Fuj8E_% zYaZYK4dc?!90C7GsE-5Z7WR85=y{JPuao=z#tHOf$o+orL~`fx&-+c|a^8#dyeENk z3;Vshm7g5rFDO4H#@|(bYK(uT{InQfXDi9?=`p^8@^8iX-paon<1>|?5#j7_bKvZ6 z&m^xiUw*lr1>Te)_si{Ua#s$1xt(KN=7%Nt8TTDmrhXr-55Vx`MEKEvGVW5 z_zlX>i}44Qe?P`wRDOPpf1vyaF~0KFlKvmY_$cKU#P~$z7m{ZrzZ|F9!C7xFio}!m zD!(|!Pf&hIg!6ix3(o6xDS4fK|9V{p-sH~fU$4u_aY%f8yu!G&-z&Ek|CQiL{;L?D z;J=zY!GDc$@!z|(_^$;|@?XdJ1poEq3H}?5OTBtwYl*uNoLgAm-cbId82?!LO)uaert@+RDN5G_bR_V#!paw2YE))&w6qR_(-5TBm70whljygAAU@} zjPZVbxQo0_?$?LA$+3~MUWLC8a*xIPp9{SgyeY$Y|8t@Dkvot7xzPKK%XNQ6)42>h zDV+~6-ueA>K4>1lpLxi*tUv!6em?j72{<>DgZJF?VTHI*``6xYg=kb1@ z?lHz^$o+Kw)I5GVe`Z|j=knX~*dTZuJbHaM0UrtU1Ua^FT-zC(*Y`>CI=O#+pQ1lQ z?x*Kza_8~W^NexH@4o7P7Cg!S9OD!G&zr~hzhGSa?dnHeP4vIS_yqsU=JEZn7#Dv| z{jY*2rT^!QPw@Z3Jih-m{|$JO|F?`!@V{Xm z-~Xm@@t>#ux4@J9Z!wJne=v{l|D$p7->d#VfhYOj zV|;@Dee?MK4~&cdW%Yjup5*^C;}iUUF^}*6t8wxFPW^uaPxAkr@d^Han8)}3)42FQ zQ~yWcN&bH^KEeO7d3^sT#>Kz>cGCZR3ZCTujPVKn&&}iegOP}bD(v5OReuwBl79r_ z6a34W$M=skF6nPk|MK8Lo#*xY&lMP-;9t=^zJDd-a$nE|KTxnTzhGm&I9~TFUnRzu zDql6mPg1^GgmYZ}J~;dT)yeC_)Bh##r1Y;r?$YC@pMR%0TK?Cme=YDJ!M`@+Gd#v0 zU)C{??_bxrl>dF|Uk^M;@UPGK1pfx+@%t zd-M4I9gIso9|b>9up_@<3+w+lvOB7XJ_&{i*>_YDRetJe5m;83B ze^>Az!9Rxa8M^%XJk~tEf1Gj2Z&vd)9-Ld)j}`U26Ugi2e!eEslNo+q{(bbMeC=*r z@>N&=9^gTOe-h&p{Ck?m&(~hYC12mxeC-X+Exe8wDBmZ-dH;SVIMcmvjQ>>melh-Q z<(U|NUwLzkH|-$)$uYjJ@|GCiQF&{O@2PwWc}DVu&n(ps1n2$2RO9~r!ZdKXF8=+( zbmL9#-)lHrJ#F-0!*%!WJNCDD-*bR*@tmlh_7u+yi}yVJ)InIgkkCo4j@zr*e_<7_R z@w4C99Gv-@PhKbY+t)$hN%`WxGmzB24lyp}HctJAf(Hry!x*2T%P+UDn8z=-1;)ic zUHylH2MPWx;}iVd=JEYG<8og)SIeyjoExtT%fDZFKE_W}zK}d4@tn7u4NlY>iT@D% z8gQ0>A9=kFyI=kV<9_)Z;XI7@e}8>r_KKCpem*0zjK=XAZIKqeJt76>GSCt%FJYO}7_kS;*|E@()XS|>O#o%(?{q!#( zcYgo()|VQWa$5y$11K2c7i_%lyk0M9zK$ZVll#}}tH%9&ea$@n^*Y+({d|4hxSy|M zz?1UD#3tqISmS=azCk~>FkkOzzK$bbHauU)lh?`pe4St(KVK(Wyq~Xc8u#;c5_nR+ zPA12x<9`q26yx%DEqJ{ccPjnZm@oEkpJ~2MBd?SD*Xwk8GUR@~zD4dle*f@o<5C~i z*-6^(8Q?*J|4ie)|15HB@p^u?#rx%Uj&Z--z5||AZr>$$e!rfdYuv97-=p8f%Xl;a z`64Rcv3n4kldZuFXs!4%XM6&{tLl_1ph^h&(P(U z^Tp=z{g)UQ|1s*n6g)`qU&i5|Mlv> z7CcDsU&r_a|Mlka{WlmF|HJCP5j;rn|A_Gk{+rC>`)@Yh?XYw)iG^)28yK~va% z|EA}?mAsB~#Ol>;^km5W>wY^q4k3?@Q+F7b_Pf^3(ths*4-))8HtzfHBF7eQzjs@_ zKmOih@zSo@Uvb>O*W&$leIK~w%OAh)CwJ%d+x0Tza=kXud_7=(zdb%^em`Fina3}; zpBNYaX!Spw;(sK?|EPI<|6|6b|Ct6q)j#DIY^)EQcO3-I{QoS*k5vA6jGv_Z3G$41 zI3K$}{ZB^X$!}5qRD{n3e;gctVljBy@li;F{Cj-MBQZqJ;7e1`;43PBHpW+0{#=Z& zs{DE5^7nP$)bqXo9z^`%d0(`6Nl$p*mts6T@5?bBp7#~w`aI>!%uf)!3Lcgl=RZ4w zv)=xkd>Lc>di4wPI=Nr3UL(gAZ!f>Jcz?Y6m2tmaybhk!E`Ck!{C>Omjq#Cg{uZ{o z-=_HAFz&azH_6q%#fZjpy|*lWMK|Bze4FL-w(*s``^0y^CH*VA``Jy<4>0t1N4Bf6s&JJjVC`f$?6+ ze`s9(e%b-*|1)@y;Qxzp-~U%~Y^*|ssA(c`{n<+`Tg?YKjtIp_shS@xb&;vfuHIT z;96erp6_m7iu~;qu<3h@iRR2>oq-_$M`bkTg3R|%16cctID?| z&oDhwPu>A%zP2K-ll%GF8aydq+mPdsc)qqZF8&YIzg>#o{kxYgJ^ppy!94zT-_f}E zn?_6ecS`Z^%=iTVm(An*cQG#hb<{sP#lLHce~fv2|5)SV-$wo8QvBmn{1eRM`zIO~ z|DNjKEycfkihmFD`2O(UBMs}%0qWl~#lKgIfA19kKE@^eS@rLm;@>aDpD~Z0{$}IS z?#l49-3Lho>*RjBXr(7Z?$_HX=J(G#)wtyA9Q992@lQ|jx0%QH?{8fE zm#hDP6n}e)e};K{|4ifJzg_+OcW9H!rz6FGpm}`%Y~$j8RQ;VP{;m}N9P{}8xyHr+ zlKSVR_~)ni4>FJMKiIhVf2;mOQv8Re_zyFW@BfN%@qeQJ1u6c+Q~X);`2KF=;@@aj z=~r_p{+<+n-aNj4p>b(G7mpq{R1ifqH({ym&n!6bcXZrvc>zKZ#)uQ(&>M`u|n=V{^uL3#wDHSXgX`= z_xq(m<9<39lRLlvIm{&%@27Jqcv3ot$eqVe=TXLG9q9^9=U2_|r}JyZ{d68p?)?7x z`PVJpzb`(u_>38umuHC5oM-l!o*h_ffPcQ{Hk=I?mf_K2e zf7keCiysmE5uE?7F}GVHJp6Zx>A96WBl+d$O#Y5zSpK(Jy!2xafw3Om4leof|6RO0 zj4$W@9g5Y*is#N0&yOwM_uOS%`u}a<;eF-Z^el7v_47y=CBXef|Fb0dnW}`@IK^`_E4wqTj{Kyl9f<>nG%Oy8Qb2Fg+P^zkWVq zet#bFsBx)3?eOz@Jx0It$a%Zc^@~wf8HmIi~mUVKbhixD#ib_ zd3^sf#>IcM`kzhlKbPWv-aNkl1>-XQo(4a!>x=Yb3&-X2l)t3Bqdz;8uXN^XwL-DC z8k8%gp21vg+MKr5peI|)9x~=I`94;^kJInt4-1-$J(W_Sr=wC@Sm@7Jf}Z@s>|lSb zGgryyi?b?)e6g0T6-vdRmaX*WYpwakg%$K@ zw_|##RxOum!O~y|yE@DL*=nC8ZgMuasJBuYEcUdN`eCR9y+L=7WmI2j$(&-LHWUpX z&f819rI>Tp;(P^VIjfw_;qchb=3-$$%EC_wJ)O0o{(LOHwUS*jqtp|}jdYvv;8JNI zb}*&?Zhynlj*C#uWy|^IYB`^)#XOC;j#8yo$rft=AYbY z*HuBSK_h7|RjX2s{2D*cW!P&3(P9p0S!WGtX2SDbLuItHLaE9c?p(-hTd}8*%hpPjS;h8J zwg)E*P$Sr=|3g%*a8$ndA7XH>=5o2M*eLYL`M&Jp0@_(y??WBPPtm>$wN+=LPA|?k$|R@^7NeyXprO_VEBQ`brvAJhJuq0y&#Lw1E6syFg;J+> zryZ4iIa|q(YMa$LYHF!6YIZ(Xs<_Kr9qb-JJ1%DXhiZjfmAQ}+0Ie(N&MsmF>n~K1 z!5R5#A8O3P5;|x(Wm~aY%N9}dD*0;RC}wkBq1aPeLdlG54i~!IZw>;R1W>jQl)0S1;ztmj~mUfqxcC^j!$}eRuTO_lNPAT$a&5JP}RU+Vk zLXn*okCO-iyh>qPjqIFSs1@_oYOol&gUu^hclmius&4G+TvDjz`l6|mzBrp}#5mG3 zzGu>KGGwd_LFLIysV}>G^C=beL>pWZGc98qFArr87HF?q``5$M;lG=U5`r zQB-rKav?XjkYD2VNl|q6;rjQq7pk>c!iT7+-lH`iAaAQ<;Hf0iB6vV z9*?f(Yw+cfx3*$=uqMqLU43L!>d3kYRaoIUIEB|pYl*aqY2`tbbH0K`#FOadmCCYv zt*-_3A(%Vc=7EbFQ$m@y%`6r3L6Kjkl}hM;&>K~Hx?Rcku(QL3#|$UPyQYfN6srZE z$W_ap>`+f7pB-RF(K(1t1P!;RBVR$^f@xq5l?*c-=BYhjtOkAfp`SlsE?PqapC-d^ zRVo-A(_3e2uN!2`XcZX3aH_T*OgIY*3#bI$gN6Q{nS%q}_!+%02eir2GH&4sb;pcC zv9o7USojLN+>CWNN5_g@9xcoDh5h~QB{_GHEwP~?71f|xs}#ypifA(EOmUtU4{oETSwMfrT0<9i;%I=)sg$YP`kT$1J#QJ_8S>{~F|Mna3Ia?*rb z`m)7hzMmXDz8e#=)kUa&81*ofkZd)It}v@pifvY>mL^Yt9;>!^R%fIr`F1vD_~-+s zEXDYUWU zgVo8|%Jf1HDh$G=EG^V#6;UtC@Z!Bi$i!Up8M%AVtWU?x0Zl48Mb$lBxEASqC+vr1Gb!q2aWz}8D zcDAJ$>nfEy`||w@+Xk||`ADqCF;forp>DNj+5gLRF>ZCBX+J%On>971sz*yV1A+7&DUcG6fmGAC7RroLEOe2@dPF~Q_{zylhQ~& zES=K7YbzRX?H^|vM$!3jpyvJh+-#+g#jv+nzISDN-CenRD}5jYb7r@9=KAsjyz7|N z*~kk!dxvJ^YuSF+rA+bHvPInGbz}Raq(s8_bzY&?=W47#?33GR%yq&Q1k7W4IQTRSle3tnbA(A^ zypQIUv7mtktwY7^fJY(+hSLmGG%w{IN8xcdzJ(XwPf=tB6;Veh65*D?ssUi*_@gvsG(VZfb`@%F8O%+hvAR`8#h2OYz(A?k znO%(gIP_aY&AA*Wt{$7!zZe(;J?fqd>M9i71cnFfUn&$?8QNqb9lm8_p20~$<2;kO zJQ6#P&w6@h6|u&KHNLi1N%;)S2)p_)kHHNy7A)*=H)*LP?de4G$PeHSs%*g+j%ryf z<&<@-XOfs?_JzZCv{rI*hoX~Y$yT_O*{;1f3VeuJ?85EX>_IjkX-Zg>z-mmXh=t5j zZDzhUr--Q%rtm#emgX=S=3GrC!ZL}=_J`sCs~oesk7$`w%w-3$FlO;pJ)ot6MatRv zGH!TK(=f>%$XBv+su(3(^Hn!nq`Y6Jox^sZc2`Pe&Nqkcs=Aw6Bo>+D6_)p%rQD)? zO{Ufzr4sr_)R5?|X50a}C8ET=Eu|vXS}`HZ4YgzbS_=<#x6vFfWO>IHe#AVdns4ct zV`U-`%Lg`-Z&lCC&RJMV;dBqHC>S*)($#Zzg4G3MhNH2=(YWDg{BSg3IGQ*d?KT|k zJ{;{a98DUIa2q%*M`OeEcMNu8AqFcueokXJB|6M;EIQ0}42L<7;V}0x9F{-~houn1 zVM)YrSQ;^GB@*XhKHZ36mtEfZ`@*ctzA(q~F3hOB3-c%M!feUAFgNlp%!IrP(=P8U z$@(@-O=mb2Zq(8UN{9**9*GK5A3#w5wHW3YM<2Y%O2e2Rng}2)7&uD6Kb&dKb;*d z$9xH#jmJjWs;!*})Ww1Do?f7i0qA=wI{K-it27wiSGZ17vCet0h?Xt(4x$6Dx`9q) zSpF)x`MkW1^j%Xbl~RSnrY(3%NaVa6bz8BP8R=^i_U@0VHkN54L6NgG*KljyjkRA* zESChZ!iZ_8b>AUsLI1rdEG6+z)uj-arXMo?HwBPgt;5fs+a z2nuUy1ckLUg2GxFL18V8AgiTO7N(!eG+f6R7%bXiQKMNV@BR13hQ*M4Y*-@6d&9y> z-W!%v^4_q>lJ|zC*MY@fJbXo#-MXk=eGcVI^wCwd4-ZDAX0j@B*$}}C3l)7#DZ8u< z%;Ze~pHqe{TILPzklt`kB*%2+@XQBmf2g_`xMh+Rsg{l1cqoy_GE`CoXV?DGGqOuH zxe##ou%jChb9&1D!FnY4u%mRBWJi)RW#PgCW*dC|tfk=QNSY}$Fh9STQ7tJ|7P*<; zLOf_gkBH8qk`^wLc@!L{H8|uIm*)1|4 zD7?~gYX-nej%$ypKi`B8UGOs+Jr)$hJ`n)jiT}=ZXxIT~cA#_N((oK}xx7DXu+~vn zn&%BW*Le{ZV$G@CuSNJ|^vj$)r|riqw^BMnN&&gX6Mme!QYvDZr+{9mRGdGfJxqef zJKLs(ys@m{R#8H%eZ9}L*Y#n~B0jgTAcs6Xo=KR34^X&#>H&So?>Raug~i$2(6mAH z!QPIU9W~yOp?!sp*?2}$a}V4w1IO|{79+Ue!c%*@W@Oz`aciOC3I%r|T_t>i0+Ye8 z`tYd(j+(+n;>m-xTB+#kB4dTSoMRashvSmq_#`-iFnl6wV;9)8Yz4D+yAK1wrAmN! zOp`-hpax@IYrcE1x2=C%u3X052v+*56UxO-S!33B;S50bP35OadUO|W>g3j!DG7L! zhJwM$d^KD#!t4R#W3I-h#&|61hIRL#*BOw2#;wUzELe7*Yt;lha z7!W-MyEu2F6KTT$SkaHJ=3C2Dhko1uqcxtkVy2*1GV4b4mhzy?L2w3Cnp|JUB6+mg;^QcIV1r}D&RK?ZPhqVSKBI)C0a@Z{1dneWhTKEN zVHEeUc#wvkeC})>-6PK?*+*lEJuj?VP8q_Ze|*98&OL|LhgEXgwjxr2M+xY0202V&#iKN(xELockCQYMxYq36&+O=m zcckTUGdnbA(v+rKWOl9Bv^=gIh1`r)l4+;}!yvmt_mQSydxn87EZ_DU#SghYsX?5g`y9`w z@gR%QxkX{|>CemyMm}D>@;F(qEV>@k0a;S82T>dd9B-XHL&q6h7p!nXYVT*{dkR@R zXO&M-QQO+yB6AE&RaYM#>lL$wM*16LfCb?}X|c!N$;D<#WA%#G#?{B!Elji3_*9zh z2`B6a4&w7C&JZ7Vk(WL!*|@sl0;0okd0b>1=0)`fVmuL#j>Jgb+{vX<%}Ok-k7uB+ zUQHPobZ2!lye=&CU{uhL)G)tu%J`r~4?i*BqR?CS*ZSsVEABHGE})u6Kg>C$Te~7+ zRlrj+JQ$O;Gk2syd0wIi4)4ncqV27U?s@pf?&L{!v4s!@;$;vXa0FF(aLj&EVehry2 zAS-YAVsnK{t?r!C&0vJa1co1LaWq_*m3Qt_Hb-HCi)Haf>d@g$!Gmc$d~DP-iN~IK z+3JA2L3J&odvp(RWy+mHIxHDk|S{}aO&e64z@Uv$z z%FiumqhjI92N@KEGf(&7h8BEc1P|^}`=m7vhuYJ`cXSSRa{?*mh^4Js9ps}9rXYf6 zmTJul(KKX7WHuCCTU}Dkx>=ll@S+P<#1(g%|`+JuyzQbHRFCSy&ho&05(IZMrbq7eJ#QX#w&i#)8sEYBJ zu%5AhcJ+b_vd%oUtGSV5ykUW`Pp<|ucmW~=ALw;=C$7g|s9_?(w6RvomHHbd*1-a* z9I9tHN5=zY6hINN{E%|=szo^#o+PgEu#e|*W*0ZDqZ8FxKUJa58MbmhY!{ZG`%6P? zJo0c$8DrtX)na+GZDU% zG+0|Cnw{@OAvuE^LS1LW9bBf8PcgV7c{k#sv;f`H9qx%V1q_kZ+G2S~)!c)R?cno7 z00~9jpqT4n^oxWEm@+HKcw#rVL1&h<6GekrSYaV%-ATK(JDY;;bx0okc+$M& z0nZSNgZ+3~jwiIbKU#Seg$s>gh_y63h*Mx+}$}P#XjydjGy*?b) zV`QkL=0Np!>Tz=Cwi67lv2_JlhL!7kJ1$xsak1^d{MfikMj|k6+?jxKA zgeP{h6?_m(T5}t2?=%=KP(R7zmbrAA=xX&+sVnHl_`xaHL!dvOJ6k_75dIp&;z|s- zkFRk_R6nw&pGf1HeWMq}Z#u{a)rcGYUy$oB4fb^6vvc_Ug=%=S$F-jBQfX1-lTC>O zryPw;a->3aEXz->{7RKx)Ghhc7k0Vxg#NtyB;CyX68Y$#d*11OqeFhLLw>6x2>$$~ z@F)L!+Y_6v@cS(%Pr3QNqrNdM_}8c0%ip6Jp<#RDI}g>tg++zny&2O8egQqcQuw`pW!$@yj>+;g7Ll!*_gjKf3Vxeq@c8gDy^3+WU}yf$z-F za`<&Byyk})17aFh(C=ZIqTl&@SmA~+7vCgXAbF9m_@};uG9Sa`MrX_AT{u7CN0>+V zq8V0spl)HFnS}5>;XeBw25C&lLmYk&3(zG8LC9J#mcJyao5h6y-_zKdv15|r-a`!k z?Tz7^l)-TR{}uAsWc=0`UTItUewI^GS*4lCalPCz860@)zY9#+w+?u7M@M^GOLJG- zteJaiyL8dKj$_7*nTXezv19pl%ozSHM0|7a+#j9;V47J|;@|ancU<@dVU3NyD2cXI zZ;*fclPeqdB^HKX#H54$O4uCN#?NDxGMy8;C*kB1_=So5|F{2_l>lo=W8<#}qTh-1 zJdJ(vpQ3$feBXcl9`!8jo<>2Ip^$YCua)s_C%iZeu>G+bha1PSZSb1XI(E15<9C_a zF@OHVvEz3ew_wbeUBWgHe&;dF?-*p5RWtfC_k~-1MbvM+mWJR9erNfFp-Iig?PG(+ z?>LXbw}qAF11IP9m{-k?T{^d8;o|*smEPG0E$J#0j;fBURSslkLl4U)WeR{jUu=t( z+ZQ`RqDJA{)ZHdEA2qo@yL5cZ)bUeVXZ8(@ua?>;cl7N(_MrUI!NUI&pNri=E-#8X z!2S9tEb_YR*fy6}YnSH9Ev;k6jh`^lT}SuRZoBU>iFnFX9v{7S(Vw}`^+{pD5qyyi z@$p0cU0=;uUJrif94j)H+AH$&g0cR)1ry`%7fhVQdi~!zSdRa#WA*=mW3B&zgJa2m zn-^ZY|JJeY|G=@{|G=^S|G=@q|G>e&zwqCdDd*b%tz+Z=fdh(R8{0BpU*z5>Jot;m z(#bw4yr25zYlq@~DhN(Eex$pW>Z+lMb~`(u{6P7*(j2u7?JEXQGn z%LwlN6F*DL)T!gAy6zL?|9%VSd^|tOj4AIZLa_tBF^