From e07c919aaeae165f9c11306a4877b5dbb757bf27 Mon Sep 17 00:00:00 2001 From: Daniel Cornelius Date: Sun, 6 Nov 2022 16:47:02 -0600 Subject: [PATCH] MSC Bug Fixes (#349) Co-authored-by: Zallist Co-authored-by: Gawi <95928592+Gawidev@users.noreply.github.com> * Update Window.mat and Window.png to support proper transparency and specularity. * Fixes #323 * Fixes #355 * Fixes #350 * Fixes #319 * Fixes #320 * Fixes #354 * Fixes #356 * Fixes #365 * Fixes #366 --- .gitignore | 10 -- Icons.zip.meta | 7 ++ LICENSE.md.meta | 7 ++ Plugins/Editor/Resources/RealtimeCSG.meta | 3 + .../Resources/{ => RealtimeCSG}/Textures.meta | 0 .../Textures/castShadows.png | Bin .../Textures/castShadows.png.meta | 0 .../{ => RealtimeCSG}/Textures/collider.png | Bin .../Textures/collider.png.meta | 0 .../{ => RealtimeCSG}/Textures/culled.png | Bin .../Textures/culled.png.meta | 0 .../{ => RealtimeCSG}/Textures/discarded.png | Bin .../Textures/discarded.png.meta | 0 .../{ => RealtimeCSG}/Textures/hidden.png | Bin .../Textures/hidden.png.meta | 0 .../{ => RealtimeCSG}/Textures/invisible.png | Bin .../Textures/invisible.png.meta | 0 .../Textures/receiveShadows.png | Bin .../Textures/receiveShadows.png.meta | 0 .../{ => RealtimeCSG}/Textures/shadowOnly.png | Bin .../Textures/shadowOnly.png.meta | 0 .../{ => RealtimeCSG}/Textures/trigger.png | Bin .../Textures/trigger.png.meta | 0 Plugins/Editor/Scripts/Control/BrushTraits.cs | 5 +- .../Editor/Scripts/Control/BrushUtility.cs | 4 +- .../Control/Helpers/ControlMeshUtility.cs | 6 +- .../Control/Helpers/ShapePolygonUtility.cs | 10 +- .../Control/Managers/CSGModelManager.cs | 7 ++ .../InternalCSGModelManager.Lifetime.cs | 67 ++++++++++- .../InternalCSGModelManager.Registration.cs | 24 ++-- .../InternalCSGModelManager.UpdateMeshes.cs | 39 ++++++- .../Managers/MeshInstanceManager.Build.cs | 23 +++- .../Control/Managers/MeshInstanceManager.cs | 106 +++++++++--------- .../Scripts/Control/Managers/UpdateLoop.cs | 4 +- .../Data/Settings/CSGProjectSettings.cs | 51 +++++++++ .../Data/Settings/CSGProjectSettings.cs.meta | 11 ++ .../Scripts/Data/Settings/CSGSettings.cs | 2 +- .../DragAndDrop/SceneDragTool.Materials.cs | 2 +- .../EditModeGUI/EditModes/EditMode.Clip.cs | 2 +- .../EditModeGUI/EditModes/EditMode.Edit.cs | 4 +- .../EditModeGUI/EditModes/EditMode.Place.cs | 11 +- .../EditModeGUI/EditModes/EditMode.Surface.cs | 12 +- .../EditModes/Generators/Generator.Base.cs | 14 +-- .../EditModes/Generators/Generator.Box.GUI.cs | 12 +- .../EditModes/Generators/Generator.Box.cs | 2 +- .../Generators/Generator.LinearStairs.cs | 4 +- .../EditModes/Generators/Generator.Sphere.cs | 4 +- .../Generators/Generator.SpiralStairs.cs | 4 +- .../CSGOptions.PreferenceWindow.cs | 80 +++++++++++-- .../Editor/Scripts/View/Scene/Grid/CSGGrid.cs | 4 +- .../Scripts/View/Scene/Grid/GridUtility.cs | 57 +++++----- .../Resources/RealtimeCSG/Materials/Floor.mat | Bin 5104 -> 0 bytes .../Resources/RealtimeCSG/Materials/Metal.mat | 57 +++++++++- .../Resources/RealtimeCSG/Materials/Wall.mat | Bin 5100 -> 0 bytes .../RealtimeCSG/Materials/Window.mat | Bin 5104 -> 0 bytes .../Resources/RealtimeCSG/Textures/Window.png | Bin 19212 -> 5887 bytes README.md | 2 +- README.md.meta | 7 ++ Readme.meta | 8 ++ Readme/Images.meta | 8 ++ Readme/Images/house_view.png.meta | 98 ++++++++++++++++ 61 files changed, 601 insertions(+), 177 deletions(-) create mode 100644 Icons.zip.meta create mode 100644 LICENSE.md.meta create mode 100644 Plugins/Editor/Resources/RealtimeCSG.meta rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/castShadows.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/castShadows.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/collider.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/collider.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/culled.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/culled.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/discarded.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/discarded.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/hidden.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/hidden.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/invisible.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/invisible.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/receiveShadows.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/receiveShadows.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/shadowOnly.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/shadowOnly.png.meta (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/trigger.png (100%) rename Plugins/Editor/Resources/{ => RealtimeCSG}/Textures/trigger.png.meta (100%) create mode 100644 Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs create mode 100644 Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs.meta create mode 100644 README.md.meta create mode 100644 Readme.meta create mode 100644 Readme/Images.meta create mode 100644 Readme/Images/house_view.png.meta diff --git a/.gitignore b/.gitignore index 623b911..c95978b 100644 --- a/.gitignore +++ b/.gitignore @@ -46,15 +46,5 @@ Logs/ ProjectSettings/ProjectVersion\.txt - *.exp - *.lib - -Packages/com\.chisel\.core/Chisel/Core/API\.private/Native/Plugin/x64/Chisel\[TEST\]\.exp\.meta -LICENSE.md.meta -Icons.zip.meta -README.md.meta -Readme.meta -Readme/Images.meta -Readme/Images/house_view.png.meta diff --git a/Icons.zip.meta b/Icons.zip.meta new file mode 100644 index 0000000..167384e --- /dev/null +++ b/Icons.zip.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c8ce9ebc0120f1446abcb89e467f34c4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/LICENSE.md.meta b/LICENSE.md.meta new file mode 100644 index 0000000..d1df217 --- /dev/null +++ b/LICENSE.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 22ae4c156efc0124e955b4d73bb8744c +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/Editor/Resources/RealtimeCSG.meta b/Plugins/Editor/Resources/RealtimeCSG.meta new file mode 100644 index 0000000..c5daea1 --- /dev/null +++ b/Plugins/Editor/Resources/RealtimeCSG.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 27c200eed1214dc7b2213b7cba612d9d +timeCreated: 1654832139 \ No newline at end of file diff --git a/Plugins/Editor/Resources/Textures.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures.meta similarity index 100% rename from Plugins/Editor/Resources/Textures.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures.meta diff --git a/Plugins/Editor/Resources/Textures/castShadows.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/castShadows.png similarity index 100% rename from Plugins/Editor/Resources/Textures/castShadows.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/castShadows.png diff --git a/Plugins/Editor/Resources/Textures/castShadows.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/castShadows.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/castShadows.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/castShadows.png.meta diff --git a/Plugins/Editor/Resources/Textures/collider.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/collider.png similarity index 100% rename from Plugins/Editor/Resources/Textures/collider.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/collider.png diff --git a/Plugins/Editor/Resources/Textures/collider.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/collider.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/collider.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/collider.png.meta diff --git a/Plugins/Editor/Resources/Textures/culled.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/culled.png similarity index 100% rename from Plugins/Editor/Resources/Textures/culled.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/culled.png diff --git a/Plugins/Editor/Resources/Textures/culled.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/culled.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/culled.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/culled.png.meta diff --git a/Plugins/Editor/Resources/Textures/discarded.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/discarded.png similarity index 100% rename from Plugins/Editor/Resources/Textures/discarded.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/discarded.png diff --git a/Plugins/Editor/Resources/Textures/discarded.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/discarded.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/discarded.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/discarded.png.meta diff --git a/Plugins/Editor/Resources/Textures/hidden.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/hidden.png similarity index 100% rename from Plugins/Editor/Resources/Textures/hidden.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/hidden.png diff --git a/Plugins/Editor/Resources/Textures/hidden.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/hidden.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/hidden.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/hidden.png.meta diff --git a/Plugins/Editor/Resources/Textures/invisible.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/invisible.png similarity index 100% rename from Plugins/Editor/Resources/Textures/invisible.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/invisible.png diff --git a/Plugins/Editor/Resources/Textures/invisible.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/invisible.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/invisible.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/invisible.png.meta diff --git a/Plugins/Editor/Resources/Textures/receiveShadows.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/receiveShadows.png similarity index 100% rename from Plugins/Editor/Resources/Textures/receiveShadows.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/receiveShadows.png diff --git a/Plugins/Editor/Resources/Textures/receiveShadows.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/receiveShadows.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/receiveShadows.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/receiveShadows.png.meta diff --git a/Plugins/Editor/Resources/Textures/shadowOnly.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/shadowOnly.png similarity index 100% rename from Plugins/Editor/Resources/Textures/shadowOnly.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/shadowOnly.png diff --git a/Plugins/Editor/Resources/Textures/shadowOnly.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/shadowOnly.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/shadowOnly.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/shadowOnly.png.meta diff --git a/Plugins/Editor/Resources/Textures/trigger.png b/Plugins/Editor/Resources/RealtimeCSG/Textures/trigger.png similarity index 100% rename from Plugins/Editor/Resources/Textures/trigger.png rename to Plugins/Editor/Resources/RealtimeCSG/Textures/trigger.png diff --git a/Plugins/Editor/Resources/Textures/trigger.png.meta b/Plugins/Editor/Resources/RealtimeCSG/Textures/trigger.png.meta similarity index 100% rename from Plugins/Editor/Resources/Textures/trigger.png.meta rename to Plugins/Editor/Resources/RealtimeCSG/Textures/trigger.png.meta diff --git a/Plugins/Editor/Scripts/Control/BrushTraits.cs b/Plugins/Editor/Scripts/Control/BrushTraits.cs index 6cc4f1f..bb49ada 100644 --- a/Plugins/Editor/Scripts/Control/BrushTraits.cs +++ b/Plugins/Editor/Scripts/Control/BrushTraits.cs @@ -39,7 +39,10 @@ public static bool IsSurfaceUnselectable(CSGBrush brush, int surfaceIndex, bool return true; } - if (ignoreSurfaceFlags) + if( (texGenFlags[texGenIndex] & TexGenFlags.NoRender) == TexGenFlags.NoRender ) + return false; + + if (ignoreSurfaceFlags) { var isNotRenderable = (texGenFlags[texGenIndex] & TexGenFlags.NoRender) == TexGenFlags.NoRender; if (!isNotRenderable) diff --git a/Plugins/Editor/Scripts/Control/BrushUtility.cs b/Plugins/Editor/Scripts/Control/BrushUtility.cs index 1f4f76f..6ca5e9e 100644 --- a/Plugins/Editor/Scripts/Control/BrushUtility.cs +++ b/Plugins/Editor/Scripts/Control/BrushUtility.cs @@ -50,7 +50,7 @@ public static void SetPivot(CSGBrush brush, Vector3 newCenter) var realCenter = transform.position; var difference = newCenter - realCenter; - if (difference.sqrMagnitude < MathConstants.ConsideredZero) + if (difference.magnitude < MathConstants.ConsideredZero) return; transform.position += difference; @@ -64,7 +64,7 @@ public static void TranslatePivot(CSGBrush[] brushes, Vector3 offset) { if (brushes == null || brushes.Length == 0 || - offset.sqrMagnitude < MathConstants.ConsideredZero) + offset.magnitude < MathConstants.ConsideredZero) return; for (int i = 0; i < brushes.Length; i++) diff --git a/Plugins/Editor/Scripts/Control/Helpers/ControlMeshUtility.cs b/Plugins/Editor/Scripts/Control/Helpers/ControlMeshUtility.cs index 6231de4..697e4ec 100644 --- a/Plugins/Editor/Scripts/Control/Helpers/ControlMeshUtility.cs +++ b/Plugins/Editor/Scripts/Control/Helpers/ControlMeshUtility.cs @@ -290,7 +290,7 @@ public static void MergeVerticesOnEdges(ControlMesh controlMesh, short[] pointIn var vertex2 = controlMesh.Vertices[vertexIndex2]; var pointOnLine = ProjectPointLine(point, vertex1, vertex2); var delta = pointOnLine - point; - var distance = delta.sqrMagnitude; + var distance = delta.magnitude; if (distance < closestDistance) { closestEdge = e; @@ -3867,7 +3867,7 @@ public static short[] FindDuplicateVerticesToRemove(CSGBrush brush, ControlMeshS for (var index2 = index1 + 1; index2 < vertices.Length; index2++) { var vertex2 = vertices[index2]; - if (!((vertex1 - vertex2).sqrMagnitude < MathConstants.EqualityEpsilon)) + if (!((vertex1 - vertex2).magnitude < MathConstants.EqualityEpsilon)) continue; //if ((pointSelectState[index1] & SelectState.Selected) != SelectState.Selected && @@ -3917,7 +3917,7 @@ public static short[] FindDuplicateVerticesToRemove(CSGBrush brush) for (var index2 = index1 + 1; index2 < vertices.Length; index2++) { var vertex2 = vertices[index2]; - if (!((vertex1 - vertex2).sqrMagnitude < MathConstants.EqualityEpsilon)) + if (!((vertex1 - vertex2).magnitude < MathConstants.EqualityEpsilon)) continue; var found = false; diff --git a/Plugins/Editor/Scripts/Control/Helpers/ShapePolygonUtility.cs b/Plugins/Editor/Scripts/Control/Helpers/ShapePolygonUtility.cs index 7fe8dfa..62ce72d 100644 --- a/Plugins/Editor/Scripts/Control/Helpers/ShapePolygonUtility.cs +++ b/Plugins/Editor/Scripts/Control/Helpers/ShapePolygonUtility.cs @@ -81,12 +81,12 @@ public static void RemoveDuplicatePoints(ref Vector3[] vertices) // remove any points that are too close to one another for (int j = vertices.Length - 1, i = vertices.Length - 2; i >= 0; j = i, i--) { - if ((vertices[j] - vertices[i]).sqrMagnitude < MathConstants.DistanceEpsilon) + if ((vertices[j] - vertices[i]).magnitude < MathConstants.DistanceEpsilon) { ArrayUtility.RemoveAt(ref vertices, j); } } - while (vertices.Length > 3 && (vertices[0] - vertices[vertices.Length - 1]).sqrMagnitude < MathConstants.DistanceEpsilon) + while (vertices.Length > 3 && (vertices[0] - vertices[vertices.Length - 1]).magnitude < MathConstants.DistanceEpsilon) { var lastIndex = vertices.Length - 1; ArrayUtility.RemoveAt(ref vertices, lastIndex); @@ -101,13 +101,13 @@ public static void RemoveDuplicatePoints(ShapePolygon shapePolygon) // remove any points that are too close to one another for (int j = vertices.Length - 1, i = vertices.Length - 2; i >= 0; j = i, i--) { - if ((vertices[j] - vertices[i]).sqrMagnitude < MathConstants.DistanceEpsilon) + if ((vertices[j] - vertices[i]).magnitude < MathConstants.DistanceEpsilon) { ArrayUtility.RemoveAt(ref vertices, j); ArrayUtility.RemoveAt(ref edgeTexgens, j); } } - while (vertices.Length > 3 && (vertices[0] - vertices[vertices.Length - 1]).sqrMagnitude < MathConstants.DistanceEpsilon) + while (vertices.Length > 3 && (vertices[0] - vertices[vertices.Length - 1]).magnitude < MathConstants.DistanceEpsilon) { var lastIndex = vertices.Length - 1; ArrayUtility.RemoveAt(ref vertices, lastIndex); @@ -159,7 +159,7 @@ private static List CreateCleanSubPolygonsFromVertices(Vector2[] v { for (int j = i + 2; j < vertices2d.Length; j++) { - if ((vertices2d[j] - vertices2d[i]).sqrMagnitude < MathConstants.DistanceEpsilon) + if ((vertices2d[j] - vertices2d[i]).magnitude < MathConstants.DistanceEpsilon) { List combined_polygons = null; diff --git a/Plugins/Editor/Scripts/Control/Managers/CSGModelManager.cs b/Plugins/Editor/Scripts/Control/Managers/CSGModelManager.cs index fbfd478..14bb1d3 100644 --- a/Plugins/Editor/Scripts/Control/Managers/CSGModelManager.cs +++ b/Plugins/Editor/Scripts/Control/Managers/CSGModelManager.cs @@ -7,6 +7,13 @@ namespace RealtimeCSG { public static class CSGModelManager { + public static bool AllowInEditorPlayMode = false; + + public static bool IsInPlayMode + { + get => !AllowInEditorPlayMode && (UnityEditor.EditorApplication.isPlaying || UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode); + } + public static void ForceRebuild() { #if UNITY_EDITOR diff --git a/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Lifetime.cs b/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Lifetime.cs index f759c25..92dfc70 100644 --- a/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Lifetime.cs +++ b/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Lifetime.cs @@ -12,7 +12,7 @@ internal partial class InternalCSGModelManager internal static NativeMethods External; #region Clear - #if UNITY_2019_4_OR_NEWER +#if UNITY_2019_4_OR_NEWER [RuntimeInitializeOnLoadMethod( RuntimeInitializeLoadType.SubsystemRegistration )] #endif public static void Clear() @@ -96,7 +96,7 @@ public static void UndoRedoPerformed() public static bool skipCheckForChanges = false; public static void CheckForChanges(bool forceHierarchyUpdate = false) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (!forceHierarchyUpdate && skipCheckForChanges) @@ -153,5 +153,68 @@ public static void ForceRebuildAll() } #endregion + +#if UNITY_EDITOR + + [UnityEditor.InitializeOnEnterPlayMode] + public static void OnEnterPlayMode() + { + // If saving meshes to scene files, we don't need to dynamically rebuild on scene changes + if (CSGProjectSettings.Instance.SaveMeshesInSceneFiles) + return; + + static bool ensureExternalMethodsPopulated() + { + if (External == null || + External.ResetCSG == null) + { + NativeMethodBindings.RegisterUnityMethods(); + NativeMethodBindings.RegisterExternalMethods(); + } + + if (External == null) + { + Debug.LogError("RealtimeCSG: Cannot rebuild meshes for some reason. External modules not loaded. Please save meshes into the Scene."); + return false; + } + + return true; + } + + static void rebuildMeshes() + { + if (!ensureExternalMethodsPopulated()) + return; + + RealtimeCSG.CSGModelManager.AllowInEditorPlayMode = true; + InternalCSGModelManager.Shutdown(); + DoForcedMeshUpdate(); + InternalCSGModelManager.CheckForChanges(false); + RealtimeCSG.CSGModelManager.AllowInEditorPlayMode = false; + } + + static void sceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode mode) + { + rebuildMeshes(); + } + + static void onPlayModeChange(PlayModeStateChange playMode) + { + if (playMode == PlayModeStateChange.EnteredEditMode) + { + UnityEngine.SceneManagement.SceneManager.sceneLoaded -= sceneLoaded; + EditorApplication.playModeStateChanged -= onPlayModeChange; + + rebuildMeshes(); + } + } + + if (!ensureExternalMethodsPopulated()) + return; + + EditorApplication.playModeStateChanged += onPlayModeChange; + UnityEngine.SceneManagement.SceneManager.sceneLoaded += sceneLoaded; + } +#endif } } \ No newline at end of file diff --git a/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Registration.cs b/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Registration.cs index 0ece289..c5f70e9 100644 --- a/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Registration.cs +++ b/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.Registration.cs @@ -79,7 +79,7 @@ static bool RegisterAllComponents() Clear(); - if (EditorApplication.isPlaying || EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) { return false; } @@ -105,7 +105,7 @@ static bool RegisterAllComponents() #region Reset public static void Reset(CSGNode node) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) { return; } @@ -122,7 +122,7 @@ public static void Reset(CSGNode node) #region AddNodeRegistration static void AddNodeRegistration(CSGNode node) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) { return; } @@ -461,7 +461,7 @@ public static void Reset(CSGModel component) #region RegisterChild static void RegisterChild(ChildNodeData childData) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; // make sure our model has actually been initialized @@ -485,7 +485,7 @@ static void RegisterChild(ChildNodeData childData) #region RegisterBrush static void RegisterBrush(CSGBrush brush) { - if (EditorApplication.isPlayingOrWillChangePlaymode || + if (RealtimeCSG.CSGModelManager.IsInPlayMode || External == null || !brush || !brush.isActiveAndEnabled || @@ -572,7 +572,7 @@ static void RegisterBrush(CSGBrush brush) #region RegisterOperation static void RegisterOperation(CSGOperation op) { - if (EditorApplication.isPlayingOrWillChangePlaymode || + if (RealtimeCSG.CSGModelManager.IsInPlayMode || External == null || !op || !op.isActiveAndEnabled || @@ -634,7 +634,7 @@ static void RegisterOperation(CSGOperation op) #region RegisterModel private static void RegisterModel(CSGModel model) { - if (EditorApplication.isPlayingOrWillChangePlaymode || + if (RealtimeCSG.CSGModelManager.IsInPlayMode || External == null || !model || !model.isActiveAndEnabled || @@ -726,7 +726,7 @@ public static void SetBrushMeshSurfaces(CSGBrush brush) #region UnregisterBrush static void UnregisterBrush(CSGBrush brush) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (External == null) @@ -773,7 +773,7 @@ static void UnregisterBrush(CSGBrush brush) #region UnregisterOperation static void UnregisterOperation(CSGOperation op) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (External == null) @@ -820,7 +820,7 @@ static void UnregisterOperation(CSGOperation op) #region UnregisterModel static void UnregisterModel(CSGModel model) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (!model.IsRegistered) @@ -862,7 +862,7 @@ static void UnregisterModel(CSGModel model) #region EnableModel private static void EnableModel(CSGModel model) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (External == null) @@ -889,7 +889,7 @@ private static void EnableModel(CSGModel model) #region DisableModel private static void DisableModel(CSGModel model) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (External == null) diff --git a/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.UpdateMeshes.cs b/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.UpdateMeshes.cs index 01167d0..d9027f0 100644 --- a/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.UpdateMeshes.cs +++ b/Plugins/Editor/Scripts/Control/Managers/InternalCSGModelManager.UpdateMeshes.cs @@ -176,7 +176,7 @@ public static bool UpdateModelSettings() #region RefreshMeshes public static void RefreshMeshes() { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (skipCheckForChanges) @@ -245,6 +245,14 @@ private static bool UpdateMesh(CSGModel model, ref outputHasGeneratedNormals, ref sharedMesh, editorOnly); + + if (!CSGProjectSettings.Instance.SaveMeshesInSceneFiles) + { + // If is prefab scene, allow save + if (string.IsNullOrEmpty(model.gameObject.scene.path) && sharedMesh != null) + sharedMesh.hideFlags &= ~HideFlags.DontSaveInEditor; + } + return true; } @@ -409,8 +417,7 @@ public static void RemoveForcedUpdates() static bool inUpdateMeshes = false; public static bool UpdateMeshes(System.Text.StringBuilder text = null, bool forceUpdate = false) { - if (EditorApplication.isPlaying - || EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return false; if (inUpdateMeshes) @@ -583,5 +590,31 @@ public static bool UpdateMeshes(System.Text.StringBuilder text = null, bool forc } } #endregion + + #region Destroy meshes + /// + /// Used to destroy any helper surface meshes in the current scene. Useful because they don't get destroyed otherwise, and stay in the Scene file. + /// + [MenuItem("Edit/Realtime-CSG/Destroy All Helper Surface Meshes In Scene")] + public static void DestroyAllHelperSurfaceCSGMeshes() + { + var allMeshesInScene = UnityEngine.Object.FindObjectsOfType(true); + + // regex matches all possible names for the helper surfaces that we can generate + var nameMatch = new System.Text.RegularExpressions.Regex( + $"^{System.Text.RegularExpressions.Regex.Escape("<")}" + + $"(?:{string.Join("|", System.Linq.Enumerable.Select(renderSurfaceMeshNames, n => System.Text.RegularExpressions.Regex.Escape(n)))})" + + $" generated -?[0-9]+{System.Text.RegularExpressions.Regex.Escape(">")}$", + System.Text.RegularExpressions.RegexOptions.Compiled); + + foreach (var mesh in allMeshesInScene) + { + if (nameMatch.IsMatch(mesh.name)) + { + Undo.DestroyObjectImmediate(mesh); + } + } + } + #endregion Destroy meshes } } \ No newline at end of file diff --git a/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.Build.cs b/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.Build.cs index 822a22d..d8bf724 100644 --- a/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.Build.cs +++ b/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.Build.cs @@ -130,7 +130,10 @@ internal static void OnBuild() } } - UnityEngine.Object.DestroyImmediate(meshContainer); + if (CSGProjectSettings.Instance.SaveMeshesInSceneFiles || !EditorApplication.isPlayingOrWillChangePlaymode) + UnityEngine.Object.DestroyImmediate(meshContainer); + else + meshContainer.hideFlags |= HideFlags.HideInHierarchy | HideFlags.HideInInspector; } @@ -139,7 +142,10 @@ internal static void OnBuild() { if (meshInstance) { - UnityEngine.Object.DestroyImmediate(meshInstance); + if (CSGProjectSettings.Instance.SaveMeshesInSceneFiles || !EditorApplication.isPlayingOrWillChangePlaymode) + UnityEngine.Object.DestroyImmediate(meshInstance); + else + meshInstance.hideFlags |= HideFlags.HideInHierarchy | HideFlags.HideInInspector; } } @@ -173,8 +179,14 @@ internal static void OnBuild() } else if (gameObject.CompareTag("Untagged")) removableGameObjects.Add(gameObject); + if (csgnode) - UnityEngine.Object.DestroyImmediate(csgnode); + { + if (CSGProjectSettings.Instance.SaveMeshesInSceneFiles || !EditorApplication.isPlayingOrWillChangePlaymode) + UnityEngine.Object.DestroyImmediate(csgnode); + else + csgnode.hideFlags |= HideFlags.HideInHierarchy | HideFlags.HideInInspector; + } } var removableTransforms = new HashSet(); @@ -184,7 +196,8 @@ internal static void OnBuild() var transform = gameObject.transform; if (removableTransforms.Contains(transform)) continue; - RemoveWithChildrenIfPossible(transform, removableTransforms); + if (CSGProjectSettings.Instance.SaveMeshesInSceneFiles || !EditorApplication.isPlayingOrWillChangePlaymode) + RemoveWithChildrenIfPossible(transform, removableTransforms); } } @@ -212,7 +225,7 @@ static bool RemoveWithChildrenIfPossible(Transform transform, HashSet internal static void DestroyAllMeshInstances() { - if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; for (var sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++) diff --git a/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.cs b/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.cs index cc577a0..b5de7ac 100644 --- a/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.cs +++ b/Plugins/Editor/Scripts/Control/Managers/MeshInstanceManager.cs @@ -42,7 +42,7 @@ public static void OnDestroyed(GeneratedMeshes container) public static void Destroy(GeneratedMeshes generatedMeshes) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (!generatedMeshes) @@ -104,6 +104,9 @@ public static void OnCreated(GeneratedMeshInstance meshInstance) static void Initialize(GeneratedMeshes container, GeneratedMeshInstance meshInstance) { + // Retain layer + meshInstance.gameObject.layer = container.gameObject.layer; + container.AddMeshInstance(meshInstance); } @@ -323,6 +326,9 @@ static GeneratedMeshes EnsureOneValidGeneratedMeshesComponent(CSGModel model) var generatedMeshesTransform = generatedMeshesObject.transform; generatedMeshesTransform.SetParent(model.transform, false); + // Retain layer + generatedMeshesObject.layer = model.gameObject.layer; + generatedMeshesObject.SetActive(true); UpdateGeneratedMeshesVisibility(generatedMeshes, model.ShowGeneratedMeshes); @@ -334,7 +340,7 @@ static GeneratedMeshes EnsureOneValidGeneratedMeshesComponent(CSGModel model) internal static bool ValidateModelNow(CSGModel model, bool checkChildren = false) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return true; if (!checkChildren && @@ -409,14 +415,14 @@ public static void UpdateHelperSurfaces() if (!ModelTraits.IsModelEditable(model)) continue; + if( !model.generatedMeshes ) + continue; + var container = model.generatedMeshes; if (container.owner != model || !container.gameObject) continue; - - if (!model.generatedMeshes) - continue; - + if (!container.HasHelperSurfaces) { if (!container.HasMeshInstances) @@ -531,7 +537,7 @@ internal static void ResetScene(Scene scene) internal static void Reset() { - if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; for (var sceneIndex = 0; sceneIndex < SceneManager.sceneCount; sceneIndex++) @@ -777,15 +783,19 @@ internal static void ClearOrCreateMesh(string baseName, bool editorOnly, ref boo hasGeneratedNormals = false; if (!recreateMeshes &&sharedMesh) { + if (!CSGProjectSettings.Instance.SaveMeshesInSceneFiles) + sharedMesh.hideFlags |= HideFlags.DontSaveInEditor; sharedMesh.Clear(keepVertexLayout: true); return; } sharedMesh = new Mesh(); - sharedMesh.name = string.Format("<{0} generated {1}>", baseName, sharedMesh.GetInstanceID()); + sharedMesh.name = $"<{baseName} generated {sharedMesh.GetInstanceID()}>"; sharedMesh.MarkDynamic(); if (editorOnly) sharedMesh.hideFlags = HideFlags.DontSaveInBuild; + if (!CSGProjectSettings.Instance.SaveMeshesInSceneFiles) + sharedMesh.hideFlags |= HideFlags.DontSaveInEditor; } public static bool UsesLightmapUVs(CSGModel model) @@ -916,33 +926,28 @@ private static bool NeedToGenerateLightmapUVsForInstance(GeneratedMeshInstance i return !instance.HasUV2 && instance.RenderSurfaceType == RenderSurfaceType.Normal; } - private static bool NeedCollider(CSGModel model, GeneratedMeshInstance instance) + private static bool AreBoundsEmpty(GeneratedMeshInstance instance) { - return //((model.HaveCollider || model.IsTrigger) && - - (//instance.RenderSurfaceType == RenderSurfaceType.Normal || - instance.RenderSurfaceType == RenderSurfaceType.Collider || - instance.RenderSurfaceType == RenderSurfaceType.Trigger - ) && - - // Make sure the bounds of the mesh are not empty ... - (Mathf.Abs(instance.SharedMesh.bounds.size.x) > MathConstants.EqualityEpsilon || - Mathf.Abs(instance.SharedMesh.bounds.size.y) > MathConstants.EqualityEpsilon || - Mathf.Abs(instance.SharedMesh.bounds.size.z) > MathConstants.EqualityEpsilon) - //) - ; + return + Mathf.Abs(instance.SharedMesh.bounds.size.x) <= MathConstants.EqualityEpsilon || + Mathf.Abs(instance.SharedMesh.bounds.size.y) <= MathConstants.EqualityEpsilon || + Mathf.Abs(instance.SharedMesh.bounds.size.z) <= MathConstants.EqualityEpsilon; + } + + private static bool NeedCollider(RenderSurfaceType surfaceType) + { + return surfaceType == RenderSurfaceType.Collider || surfaceType == RenderSurfaceType.Trigger; } - private static bool NeedMeshRenderer(RenderSurfaceType renderSurfaceType) + private static bool NeedMeshRenderer(RenderSurfaceType renderSurfaceType) { - return (renderSurfaceType == RenderSurfaceType.Normal || - renderSurfaceType == RenderSurfaceType.ShadowOnly); + return renderSurfaceType == RenderSurfaceType.Normal || renderSurfaceType == RenderSurfaceType.ShadowOnly; } static StaticEditorFlags FilterStaticEditorFlags(StaticEditorFlags modelStaticFlags, RenderSurfaceType renderSurfaceType) { if (!NeedMeshRenderer(renderSurfaceType)) - return (StaticEditorFlags)0; + return modelStaticFlags; var meshStaticFlags = modelStaticFlags; var walkable = renderSurfaceType != RenderSurfaceType.Hidden && @@ -1026,7 +1031,7 @@ public static void Refresh(CSGModel model, bool postProcessScene = false, bool o // internal static double updateMeshColliderMeshTime = 0.0; public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool postProcessScene = false, bool onlyFastRefreshes = true, bool skipAssetDatabaseUpdate = true) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (!instance) @@ -1084,7 +1089,6 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool var meshFilterComponent = instance.CachedMeshFilter; var meshRendererComponent = instance.CachedMeshRenderer; - var needMeshCollider = NeedCollider(owner, instance); @@ -1173,12 +1177,12 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool if ((meshFilterComponent.hideFlags & HideFlags.HideInHierarchy) == 0) { meshFilterComponent.hideFlags |= HideFlags.HideInHierarchy; - } - - if ((meshRendererComponent.hideFlags & HideFlags.HideInHierarchy) == 0) + } + + if ((meshRendererComponent.hideFlags & HideFlags.HideInHierarchy) == 0) { meshRendererComponent.hideFlags |= HideFlags.HideInHierarchy; - } + } if (instance.RenderSurfaceType != RenderSurfaceType.ShadowOnly) { @@ -1188,7 +1192,7 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool instance.ResetUVTime = Time.realtimeSinceStartup; if (instance.HasUV2) ClearUVs(instance); - } + } if ((owner.AutoRebuildUVs || postProcessScene)) { @@ -1309,8 +1313,8 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool if (SOModified) meshRendererComponentSO.ApplyModifiedProperties(); - } - } + } + } //*/ #if UNITY_2019_2_OR_NEWER @@ -1328,7 +1332,7 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool { meshRendererComponent.sharedMaterial = requiredMaterial; instance.Dirty = true; - } + } } else { @@ -1353,6 +1357,8 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool // TODO: occludee/reflection probe static var meshColliderComponent = instance.CachedMeshCollider; + var needMeshCollider = !AreBoundsEmpty(instance) && NeedCollider(instance.RenderSurfaceType); + if (needMeshCollider) { if (!meshColliderComponent) @@ -1373,10 +1379,10 @@ public static void Refresh(GeneratedMeshInstance instance, CSGModel owner, bool meshColliderComponent.hideFlags |= HideFlags.HideInHierarchy; } - var currentPhyicsMaterial = instance.PhysicsMaterial ?? owner.DefaultPhysicsMaterial; - if (meshColliderComponent.sharedMaterial != currentPhyicsMaterial) + var currentPhysicsMaterial = instance.PhysicsMaterial ?? owner.DefaultPhysicsMaterial; + if (meshColliderComponent.sharedMaterial != currentPhysicsMaterial) { - meshColliderComponent.sharedMaterial = currentPhyicsMaterial; + meshColliderComponent.sharedMaterial = currentPhysicsMaterial; instance.Dirty = true; } @@ -1492,7 +1498,7 @@ private static void UpdateName(GeneratedMeshInstance instance) public static void UpdateHelperSurfaceVisibility(bool force = false) { - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; // updateMeshColliderMeshTime = 0.0; @@ -1623,9 +1629,9 @@ static void AutoUpdateRigidBody(GeneratedMeshes container) constraints = RigidbodyConstraints.None; } - if (rigidBody.isKinematic != isKinematic) rigidBody.isKinematic = isKinematic; - if (rigidBody.useGravity != useGravity) rigidBody.useGravity = useGravity; - if (rigidBody.constraints != constraints) rigidBody.constraints = constraints; + if (rigidBody.isKinematic != isKinematic) rigidBody.isKinematic = isKinematic; + if (rigidBody.useGravity != useGravity) rigidBody.useGravity = useGravity; + if (rigidBody.constraints != constraints) rigidBody.constraints = constraints; container.CachedRigidBody = rigidBody; } else { @@ -1661,7 +1667,7 @@ public static void RemoveIfEmpty(GameObject gameObject) public static bool ValidateGeneratedMeshesNow(GeneratedMeshes generatedMeshes, bool skipSiblingCheck = false) { - if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return false; if (!generatedMeshes) @@ -1820,7 +1826,7 @@ static void UpdateTransform(GeneratedMeshes container) return; } - if (EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; // TODO: make sure outlines are updated when models move @@ -1843,7 +1849,7 @@ static void UpdateTransform(GeneratedMeshes container) public static List FindUnusedMeshInstances(GeneratedMeshes container, HashSet foundInstances) { - if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return null; if (!container || !container.owner) @@ -1892,7 +1898,7 @@ public static void UpdateContainerComponents(GeneratedMeshes container, HashSet foundInstances, HashSet foundHelperSurfaces) { - if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) + if (RealtimeCSG.CSGModelManager.IsInPlayMode) return; if (!container || !container.owner) @@ -2026,9 +2032,9 @@ private static void UpdateContainerFlags(GeneratedMeshes generatedMeshes) var showVisibleSurfaces = (RealtimeCSG.CSGSettings.VisibleHelperSurfaces & HelperSurfaceFlags.ShowVisibleSurfaces) != 0; - if (ownerStaticFlags != previousStaticFlags || - !ownerGameObject.CompareTag(generatedMeshes.gameObject.tag) || - containerLayer != generatedMeshes.gameObject.layer) + if (ownerStaticFlags != previousStaticFlags + || !ownerGameObject.CompareTag(generatedMeshes.gameObject.tag) + || containerLayer != generatedMeshes.gameObject.layer) { var containerTag = ownerGameObject.tag; foreach (var meshInstance in generatedMeshes.MeshInstances) diff --git a/Plugins/Editor/Scripts/Control/Managers/UpdateLoop.cs b/Plugins/Editor/Scripts/Control/Managers/UpdateLoop.cs index 3203150..6c9f6ac 100644 --- a/Plugins/Editor/Scripts/Control/Managers/UpdateLoop.cs +++ b/Plugins/Editor/Scripts/Control/Managers/UpdateLoop.cs @@ -251,8 +251,8 @@ void OnWaitUntillStoppedPlaying() static void RunEditorUpdate() { - if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG) - return; + //if (!RealtimeCSG.CSGSettings.EnableRealtimeCSG) + // return; if (EditorApplication.isPlayingOrWillChangePlaymode) return; diff --git a/Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs b/Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs new file mode 100644 index 0000000..8498329 --- /dev/null +++ b/Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs @@ -0,0 +1,51 @@ +using UnityEngine; +using UnityEditor; +using UnityEditorInternal; +using System.IO; + +namespace RealtimeCSG +{ + public class CSGProjectSettings : ScriptableObject + { + const string ASSET_PATH = "ProjectSettings/CSGProjectSettings.asset"; + + private static CSGProjectSettings s_Instance; + public static CSGProjectSettings Instance => s_Instance == null ? CreateOrLoad() : s_Instance; + + public bool SaveMeshesInSceneFiles = true; + public bool SnapEverythingTo0001Grid = true; + + CSGProjectSettings() + { + s_Instance = this; + } + + private static CSGProjectSettings CreateOrLoad() + { + InternalEditorUtility.LoadSerializedFileAndForget(ASSET_PATH); + + if (s_Instance == null) + { + var created = CreateInstance(); + created.hideFlags = HideFlags.HideAndDontSave; + } + + System.Diagnostics.Debug.Assert(s_Instance != null); + return s_Instance; + } + + public void Save() + { + if (s_Instance == null) + { + Debug.Log("Cannot save ScriptableSingleton: no instance!"); + return; + } + + string folderPath = Path.GetDirectoryName(ASSET_PATH); + if (!Directory.Exists(folderPath)) + Directory.CreateDirectory(folderPath); + InternalEditorUtility.SaveToSerializedFileAndForget(new[] { s_Instance }, ASSET_PATH, allowTextSerialization: true); + } + } +} diff --git a/Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs.meta b/Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs.meta new file mode 100644 index 0000000..05a5308 --- /dev/null +++ b/Plugins/Editor/Scripts/Data/Settings/CSGProjectSettings.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5e3f6e022f116d48896fab59bdf2871 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Plugins/Editor/Scripts/Data/Settings/CSGSettings.cs b/Plugins/Editor/Scripts/Data/Settings/CSGSettings.cs index 0af09f3..e6239aa 100644 --- a/Plugins/Editor/Scripts/Data/Settings/CSGSettings.cs +++ b/Plugins/Editor/Scripts/Data/Settings/CSGSettings.cs @@ -761,7 +761,7 @@ public static void Save() builder.Append(sceneView.name); } } - EditorPrefs.SetString("Wireframe", builder.ToString()); + EditorPrefs.SetString("Wireframe", builder.ToString()); } #endregion diff --git a/Plugins/Editor/Scripts/View/DragAndDrop/SceneDragTool.Materials.cs b/Plugins/Editor/Scripts/View/DragAndDrop/SceneDragTool.Materials.cs index b5f6c1e..bbad813 100644 --- a/Plugins/Editor/Scripts/View/DragAndDrop/SceneDragTool.Materials.cs +++ b/Plugins/Editor/Scripts/View/DragAndDrop/SceneDragTool.Materials.cs @@ -561,7 +561,7 @@ void ApplyMaterial(SelectedBrushSurface[] hoverBrushSurfaces) var material = GetMaterial(); if (texGens[m].RenderMaterial != material) { - if (!modified) + if (modified) { UndoInit(); Undo.RecordObject(brush, "Modifying material"); diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Clip.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Clip.cs index 01b9b14..5f4d813 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Clip.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Clip.cs @@ -953,7 +953,7 @@ void CreateFirstPoint(SceneView sceneView) RecordAllObjects("Created clip plane"); - if ((points[2] - points[1]).sqrMagnitude < 0.1f) + if ((points[2] - points[1]).magnitude < 0.1f) { var direction = -normal; var snapVector = RealtimeCSG.CSGGrid.CurrentGridSnapVector; diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Edit.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Edit.cs index dc33d26..3e4b289 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Edit.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Edit.cs @@ -2001,7 +2001,7 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) { if (Event.current.button != 0) _nonZeroMouseIsDown = true; - if (!_mouseIsDragging && (_prevMousePos - Event.current.mousePosition).sqrMagnitude > 4.0f) + if (!_mouseIsDragging && (_prevMousePos - Event.current.mousePosition).magnitude > 4.0f) _mouseIsDragging = true; break; } @@ -2623,7 +2623,7 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) if (!_showMarquee) { - if ((_startMousePoint - Event.current.mousePosition).sqrMagnitude > + if ((_startMousePoint - Event.current.mousePosition).magnitude > (MathConstants.MinimumMouseMovement * MathConstants.MinimumMouseMovement)) { _brushSelection.BackupSelection(); diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Place.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Place.cs index 5f48065..ffaf014 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Place.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Place.cs @@ -1315,7 +1315,7 @@ void RenderRotationCircle(Camera camera) PaintUtility.DrawDottedLine(rotateCenter, rotateMousePosition, ColorSettings.BoundsEdgeHover); - if ((worldSpacePivotCenter - rotateCenter).sqrMagnitude > MathConstants.EqualityEpsilon) + if ((worldSpacePivotCenter - rotateCenter).magnitude > MathConstants.EqualityEpsilon) { PaintUtility.DrawDottedLine(worldSpacePivotCenter, rotateCenter, ColorSettings.BoundsEdgeHover); PaintUtility.DrawProjectedPivot(camera, rotateCenter, ColorSettings.BoundsEdgeHover); @@ -1359,12 +1359,13 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) var inCamera = (camera != null) && camera.pixelRect.Contains(Event.current.mousePosition); var originalEventType = Event.current.type; - if (originalEventType == EventType.MouseMove) { mouseIsDragging = false; draggingOnCamera = null; realMousePosition = Event.current.mousePosition; } - else if (originalEventType == EventType.MouseDown) { mouseIsDragging = false; draggingOnCamera = camera; realMousePosition = prevMousePos = Event.current.mousePosition; } - else if (originalEventType == EventType.MouseUp) { draggingOnCamera = null; } + if( Event.current.type == EventType.MouseMove ) { sceneView.Repaint(); } + else if (originalEventType == EventType.MouseMove) { mouseIsDragging = false; draggingOnCamera = null; realMousePosition = Event.current.mousePosition; } + else if (originalEventType == EventType.MouseDown) { mouseIsDragging = false; draggingOnCamera = camera; realMousePosition = prevMousePos = Event.current.mousePosition; } + else if (originalEventType == EventType.MouseUp) { draggingOnCamera = null; } else if (originalEventType == EventType.MouseDrag) { - if (!mouseIsDragging && (prevMousePos - Event.current.mousePosition).sqrMagnitude > 4.0f) + if (!mouseIsDragging && (prevMousePos - Event.current.mousePosition).magnitude > 4.0f) { mouseIsDragging = true; } diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Surface.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Surface.cs index fed1d3c..c8b9383 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Surface.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/EditMode.Surface.cs @@ -959,7 +959,7 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) else if (originalEventType == EventType.MouseDrag) { mouseIsDown = true; - if (!mouseIsDragging && (prevMousePos - Event.current.mousePosition).sqrMagnitude > 4.0f) + if (!mouseIsDragging && (prevMousePos - Event.current.mousePosition).magnitude > 4.0f) mouseIsDragging = true; } @@ -1344,7 +1344,7 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) { for (int p = 0; p < surfaceState.surfaceSelectState.Length; p++) { - if (surfaceState.surfaceSelectState[p] != oldSurfaceStates[p]) + if (surfaceState.surfaceSelectState[p] != oldSurfaceStates[p] || oldSurfaceStates[p] == SelectState.None) repaint = true; } } @@ -1353,9 +1353,6 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) editMode = newEditMode; Handles.matrix = origMatrix; - if (repaint) - CSG_EditorGUIUtility.RepaintAll(); - if (hoverOnTarget >= 0 && hoverOnSurfaceIndex >= 0 && surfaceStates.Length > hoverOnTarget && surfaceStates[hoverOnTarget].surfaceSelectState.Length > hoverOnSurfaceIndex) { @@ -1365,6 +1362,10 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) currentCursor = MouseCursor.ArrowPlus; } } + + if( repaint ) + CSG_EditorGUIUtility.RepaintAll(); + break; } } @@ -1585,6 +1586,7 @@ public void HandleEvents(SceneView sceneView, Rect sceneRect) if (originalEventType == EventType.MouseUp || originalEventType == EventType.MouseMove) { mouseIsDragging = false; mouseIsDown = false; } } + } diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Base.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Base.cs index ed9f936..f6b8823 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Base.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Base.cs @@ -398,7 +398,7 @@ protected void CalculateWorldSpaceTangents(Camera camera) } } - protected void SetCameraPosition(SceneView sceneView, Vector3 center, float size) + /*protected void SetCameraPosition(SceneView sceneView, Vector3 center, float size) { if (float.IsInfinity(size) || float.IsNaN(size) || float.IsInfinity(center.x) || float.IsNaN(center.x) || @@ -407,7 +407,7 @@ protected void SetCameraPosition(SceneView sceneView, Vector3 center, float size return; if (sceneView) sceneView.LookAt(center, sceneView.rotation, Mathf.Max(size, (sceneView.camera.transform.position - center).magnitude)); - } + }*/ protected void HideGenerateBrushes() @@ -622,7 +622,7 @@ internal void MarkAllBrushesDirty() public abstract AABB GetShapeBounds(); - protected void HandleCameraOrbit(SceneView sceneView, bool allowCameraOrbit) + /*protected void HandleCameraOrbit(SceneView sceneView, bool allowCameraOrbit) { if (!ignoreOrbit && Tools.viewTool == ViewTool.Orbit && @@ -638,7 +638,7 @@ protected void HandleCameraOrbit(SceneView sceneView, bool allowCameraOrbit) if (Event.current.type == EventType.MouseUp || Event.current.type == EventType.MouseMove) ignoreOrbit = false; - } + }*/ public bool UndoRedoPerformed() @@ -658,9 +658,9 @@ public virtual void HandleEvents(SceneView sceneView, Rect sceneRect) CreateControlIDs(); - if (mouseIsDragging || - (Event.current.type == EventType.MouseDown && Tools.viewTool == ViewTool.Orbit)) - HandleCameraOrbit(sceneView, editMode != EditMode.CreatePlane); + //if (mouseIsDragging || + // (Event.current.type == EventType.MouseDown && Tools.viewTool == ViewTool.Orbit)) + // HandleCameraOrbit(sceneView, editMode != EditMode.CreateShape && editMode != EditMode.CreatePlane); // pretend we dragged so we don't click if we just changed edit modes if (prevEditMode != editMode) diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.GUI.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.GUI.cs index 0a550ac..127cf7f 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.GUI.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.GUI.cs @@ -51,14 +51,14 @@ static void BoxSettingsGUI(GeneratorBox generator, bool isSceneGUI) GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); { GUILayout.Label(LengthContent, Width65); - var length = generator.Length; + var width = generator.Width; EditorGUI.BeginChangeCheck(); { - length = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, length))); + width = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, width))); } if (EditorGUI.EndChangeCheck()) { - generator.Length = length; + generator.Width = width; } if (GUILayout.Button(unitText, EditorStyles.miniLabel, Width25)) { @@ -74,14 +74,14 @@ static void BoxSettingsGUI(GeneratorBox generator, bool isSceneGUI) GUILayout.BeginHorizontal(CSG_GUIStyleUtility.ContentEmpty); { GUILayout.Label(WidthContent, Width65); - var width = generator.Width; + var length = generator.Length; EditorGUI.BeginChangeCheck(); { - width = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, width))); + length = Units.DistanceUnitToUnity(distanceUnit, EditorGUILayout.DoubleField(Units.UnityToDistanceUnit(distanceUnit, length))); } if (EditorGUI.EndChangeCheck()) { - generator.Width = width; + generator.Length = length; } if (GUILayout.Button(unitText, EditorStyles.miniLabel, Width25)) { diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.cs index 8955c9b..1553d4d 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Box.cs @@ -157,7 +157,7 @@ public bool HotKeyReleased() settings.AddPoint(worldPosition); } - if ((settings.vertices[0] - settings.vertices[1]).sqrMagnitude <= MathConstants.EqualityEpsilon) + if ((settings.vertices[0] - settings.vertices[1]).magnitude <= MathConstants.EqualityEpsilon) { Cancel(); return false; diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.LinearStairs.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.LinearStairs.cs index af18604..aaa6c78 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.LinearStairs.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.LinearStairs.cs @@ -257,7 +257,7 @@ public bool HotKeyReleased() settings.bounds = GetShapeBounds(); } - if ((settings.vertices[0] - settings.vertices[1]).sqrMagnitude <= MathConstants.EqualityEpsilon) + if ((settings.vertices[0] - settings.vertices[1]).magnitude <= MathConstants.EqualityEpsilon) { Cancel(); return false; @@ -821,7 +821,7 @@ protected override void HandleCreateShapeEvents(SceneView sceneView, Rect sceneR prevWorldPosition = worldPosition; if (settings.vertices.Length > 0) { - if ((settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon) + if ((settings.vertices[0] - worldPosition).magnitude > MathConstants.EqualityEpsilon) { UpdateSizes(); UpdateBaseShape(true); diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.cs index 2b0672d..c5663f6 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.Sphere.cs @@ -103,7 +103,7 @@ public bool HotKeyReleased() settings.AddPoint(worldPosition); } - if ((settings.vertices[0] - settings.vertices[1]).sqrMagnitude <= MathConstants.EqualityEpsilon) + if ((settings.vertices[0] - settings.vertices[1]).magnitude <= MathConstants.EqualityEpsilon) { Cancel(); return false; @@ -642,7 +642,7 @@ protected override void HandleCreateShapeEvents(SceneView sceneView, Rect sceneR prevWorldPosition = worldPosition; if (settings.vertices.Length > 0) { - if (hadSphere || (settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon) + if (hadSphere || (settings.vertices[0] - worldPosition).magnitude > MathConstants.EqualityEpsilon) { hadSphere = true; UpdateBaseShape(true); diff --git a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.SpiralStairs.cs b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.SpiralStairs.cs index 2687ba8..26f8f9e 100644 --- a/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.SpiralStairs.cs +++ b/Plugins/Editor/Scripts/View/GUI/EditModeGUI/EditModes/Generators/Generator.SpiralStairs.cs @@ -256,7 +256,7 @@ public bool HotKeyReleased() settings.bounds = GetShapeBounds(); } - if ((settings.vertices[0] - settings.vertices[1]).sqrMagnitude <= MathConstants.EqualityEpsilon) + if ((settings.vertices[0] - settings.vertices[1]).magnitude <= MathConstants.EqualityEpsilon) { Cancel(); return false; @@ -810,7 +810,7 @@ protected override void HandleCreateShapeEvents(SceneView sceneView, Rect sceneR prevWorldPosition = worldPosition; if (settings.vertices.Length > 0) { - if ((settings.vertices[0] - worldPosition).sqrMagnitude > MathConstants.EqualityEpsilon) + if ((settings.vertices[0] - worldPosition).magnitude > MathConstants.EqualityEpsilon) { UpdateSizes(); UpdateBaseShape(true); diff --git a/Plugins/Editor/Scripts/View/GUI/PreferenceWindows/CSGOptions.PreferenceWindow.cs b/Plugins/Editor/Scripts/View/GUI/PreferenceWindows/CSGOptions.PreferenceWindow.cs index fd08ebb..66ed912 100644 --- a/Plugins/Editor/Scripts/View/GUI/PreferenceWindows/CSGOptions.PreferenceWindow.cs +++ b/Plugins/Editor/Scripts/View/GUI/PreferenceWindows/CSGOptions.PreferenceWindow.cs @@ -15,13 +15,17 @@ public static void PreferenceWindow() { EditorGUI.BeginChangeCheck(); { - CSGSettings.ShowTooltips = EditorGUILayout.ToggleLeft("Show Tool-Tips", CSGSettings.ShowTooltips); - CSGSettings.SnapNonCSGObjects = EditorGUILayout.ToggleLeft("Snap Non-CSG Objects to the grid", CSGSettings.SnapNonCSGObjects); - CSGSettings.AutoRigidbody = EditorGUILayout.ToggleLeft("Disable auto add rigidbodies", CSGSettings.AutoRigidbody); - CSGSettings.DefaultPreserveUVs = EditorGUILayout.ToggleLeft("Preserve UVs (Default)", CSGSettings.DefaultPreserveUVs); +#if !UNITY_2018_4_OR_NEWER && !UNITY_2019_1_OR_NEWER + CSGProjectSettings.Instance.SaveMeshesInSceneFiles = EditorGUILayout.ToggleLeft("Save Meshes In Scene Files", CSGProjectSettings.Instance.SaveMeshesInSceneFiles); + EditorGUILayout.Separator(); +#endif + CSGSettings.ShowTooltips = EditorGUILayout.ToggleLeft("Show Tool-Tips", CSGSettings.ShowTooltips); + CSGSettings.SnapNonCSGObjects = EditorGUILayout.ToggleLeft("Snap Non-CSG Objects to the grid", CSGSettings.SnapNonCSGObjects); + CSGSettings.AutoRigidbody = EditorGUILayout.ToggleLeft("Disable auto add rigidbodies", CSGSettings.AutoRigidbody); + CSGSettings.DefaultPreserveUVs = EditorGUILayout.ToggleLeft("Preserve UVs (Default)", CSGSettings.DefaultPreserveUVs); EditorGUILayout.Space(); - CSGSettings.MaxCircleSides = EditorGUILayout.IntField("Max Circle Sides", CSGSettings.MaxCircleSides); - CSGSettings.MaxSphereSplits = EditorGUILayout.IntField("Max Sphere Splits", CSGSettings.MaxSphereSplits); + CSGSettings.MaxCircleSides = EditorGUILayout.IntField("Max Circle Sides", CSGSettings.MaxCircleSides); + CSGSettings.MaxSphereSplits = EditorGUILayout.IntField("Max Sphere Splits", CSGSettings.MaxSphereSplits); EditorGUILayout.Space(); EditorGUILayout.LabelField("Surfaces", EditorStyles.boldLabel); @@ -35,13 +39,48 @@ public static void PreferenceWindow() CSGSettings.DefaultTexGenFlags |= TexGenFlags.WorldSpaceTexture; } - CSGSettings.ShowSceneInfo = EditorGUILayout.ToggleLeft( "Show Scene Info", CSGSettings.ShowSceneInfo ); + CSGSettings.ShowSceneInfo = EditorGUILayout.ToggleLeft("Show Scene Info", CSGSettings.ShowSceneInfo); } if (EditorGUI.EndChangeCheck()) { +#if !UNITY_2018_4_OR_NEWER && !UNITY_2019_1_OR_NEWER + CSGProjectSettings.Instance.Save(); +#endif CSGSettings.Save(); } } + + public static void ProjectSettingsWindow() + { + EditorGUI.BeginChangeCheck(); + { + CSGProjectSettings.Instance.SaveMeshesInSceneFiles = !EditorGUILayout.ToggleLeft("[Experimental] Don't Save Meshes In Scene Files", !CSGProjectSettings.Instance.SaveMeshesInSceneFiles); + + if (!CSGProjectSettings.Instance.SaveMeshesInSceneFiles) + { + EditorGUILayout.HelpBox( + "Meshes will be rebuilt on editor & scene load. This is an experimental option, if meshes are not rebuilding properly, please disable it.", + MessageType.Warning, true); + } + else + { + EditorGUILayout.HelpBox( + "If enabled, meshes will be automatically rebuilt on editor & scene load, dramatically saving disk space.", + MessageType.Info, true); + } + + CSGProjectSettings.Instance.SnapEverythingTo0001Grid = EditorGUILayout.ToggleLeft("Snap All CSG Objects To 0.001 Grid", CSGProjectSettings.Instance.SnapEverythingTo0001Grid); + EditorGUILayout.HelpBox( + "If enabled, every CSG object will snap to a small grid regardless of snapping options. " + + "This ensures things line up when on a tiny scale, but can make it difficult to work at a small scale.", + MessageType.Info, true); + } + + if (EditorGUI.EndChangeCheck()) + { + CSGProjectSettings.Instance.Save(); + } + } } #if UNITY_2018_4_OR_NEWER @@ -49,7 +88,7 @@ public static void PreferenceWindow() static class RealtimeCSGOptionsIMGUIRegister { [SettingsProvider] - public static SettingsProvider CreateMyCustomSettingsProvider() + public static SettingsProvider CreateCSGPreferenceSettings() { var keys = CSGKeysPreferenceWindow.GetKeys(); var keywords = new HashSet(); @@ -60,16 +99,16 @@ public static SettingsProvider CreateMyCustomSettingsProvider() keywords.Add(piece); } - var provider = new SettingsProvider("Project/RealtimeCSG", SettingsScope.Project) + var provider = new SettingsProvider("Preferences/RealtimeCSG", SettingsScope.User) { label = "Realtime CSG", + guiHandler = (searchContext) => { GUILayout.Label("Options", EditorStyles.boldLabel); GUILayout.Space(10); CSGOptionsPreferenceWindow.PreferenceWindow(); - - GUILayout.Space(30); + EditorGUILayout.Separator(); GUILayout.Label("Keyboard settings", EditorStyles.boldLabel); GUILayout.Space(10); CSGKeysPreferenceWindow.PreferenceWindow(); @@ -80,6 +119,25 @@ public static SettingsProvider CreateMyCustomSettingsProvider() return provider; } + + [SettingsProvider] + public static SettingsProvider CreateCSGProjectSettings() + { + var provider = new SettingsProvider("Project/RealtimeCSGProjectSettings", SettingsScope.Project) + { + label = "Realtime CSG", + guiHandler = (searchContext) => + { + GUILayout.Label("Options", EditorStyles.boldLabel); + GUILayout.Space(10); + CSGOptionsPreferenceWindow.ProjectSettingsWindow(); + }, + + keywords = new[] { "Meshes" } + }; + + return provider; + } } #endif } diff --git a/Plugins/Editor/Scripts/View/Scene/Grid/CSGGrid.cs b/Plugins/Editor/Scripts/View/Scene/Grid/CSGGrid.cs index 9842568..aeeb77c 100644 --- a/Plugins/Editor/Scripts/View/Scene/Grid/CSGGrid.cs +++ b/Plugins/Editor/Scripts/View/Scene/Grid/CSGGrid.cs @@ -248,8 +248,8 @@ static void OnRender(Camera camera) Vector3 forward = gridOrientation.gridRotation * MathConstants.forwardVector3; Vector3 work_forward = gridOrientation.gridWorkRotation * MathConstants.forwardVector3; if (ForceGrid && - !((forward - work_forward).sqrMagnitude < 0.001f || - (forward + work_forward).sqrMagnitude < 0.001f + !((forward - work_forward).magnitude < 0.001f || + (forward + work_forward).magnitude < 0.001f // && gridOrientation.grid_work_center == gridOrientation.grid_center )) { diff --git a/Plugins/Editor/Scripts/View/Scene/Grid/GridUtility.cs b/Plugins/Editor/Scripts/View/Scene/Grid/GridUtility.cs index 5db1a2c..5d9afa4 100644 --- a/Plugins/Editor/Scripts/View/Scene/Grid/GridUtility.cs +++ b/Plugins/Editor/Scripts/View/Scene/Grid/GridUtility.cs @@ -67,40 +67,43 @@ static public Vector3 CleanNormal(Vector3 normal) static public Vector3 CleanPosition(Vector3 position) { - float signX = Mathf.Sign(position.x); - float signY = Mathf.Sign(position.y); - float signZ = Mathf.Sign(position.z); - - float absPosX = position.x * signX; - float absPosY = position.y * signY; - float absPosZ = position.z * signZ; + if (CSGProjectSettings.Instance.SnapEverythingTo0001Grid) + { + float signX = Mathf.Sign(position.x); + float signY = Mathf.Sign(position.y); + float signZ = Mathf.Sign(position.z); - int intPosX = Mathf.FloorToInt(absPosX); - int intPosY = Mathf.FloorToInt(absPosY); - int intPosZ = Mathf.FloorToInt(absPosZ); + float absPosX = position.x * signX; + float absPosY = position.y * signY; + float absPosZ = position.z * signZ; - float fractPosX = (absPosX - intPosX); - float fractPosY = (absPosY - intPosY); - float fractPosZ = (absPosZ - intPosZ); + int intPosX = Mathf.FloorToInt(absPosX); + int intPosY = Mathf.FloorToInt(absPosY); + int intPosZ = Mathf.FloorToInt(absPosZ); - fractPosX = Mathf.Round(fractPosX * 1000.0f) / 1000.0f; - fractPosY = Mathf.Round(fractPosY * 1000.0f) / 1000.0f; - fractPosZ = Mathf.Round(fractPosZ * 1000.0f) / 1000.0f; + float fractPosX = (absPosX - intPosX); + float fractPosY = (absPosY - intPosY); + float fractPosZ = (absPosZ - intPosZ); - const float epsilon = MathConstants.EqualityEpsilon; + fractPosX = Mathf.Round(fractPosX * 1000.0f) / 1000.0f; + fractPosY = Mathf.Round(fractPosY * 1000.0f) / 1000.0f; + fractPosZ = Mathf.Round(fractPosZ * 1000.0f) / 1000.0f; - if (fractPosX < epsilon) fractPosX = 0; - if (fractPosY < epsilon) fractPosY = 0; - if (fractPosZ < epsilon) fractPosZ = 0; + const float epsilon = MathConstants.EqualityEpsilon; - if (fractPosX >= 1 - epsilon) fractPosX = 1; - if (fractPosY >= 1 - epsilon) fractPosY = 1; - if (fractPosZ >= 1 - epsilon) fractPosZ = 1; + if (fractPosX < epsilon) fractPosX = 0; + if (fractPosY < epsilon) fractPosY = 0; + if (fractPosZ < epsilon) fractPosZ = 0; + + if (fractPosX >= 1 - epsilon) fractPosX = 1; + if (fractPosY >= 1 - epsilon) fractPosY = 1; + if (fractPosZ >= 1 - epsilon) fractPosZ = 1; + + if (!float.IsNaN(fractPosX) && !float.IsInfinity(fractPosX)) position.x = (intPosX + fractPosX) * signX; + if (!float.IsNaN(fractPosY) && !float.IsInfinity(fractPosY)) position.y = (intPosY + fractPosY) * signY; + if (!float.IsNaN(fractPosZ) && !float.IsInfinity(fractPosZ)) position.z = (intPosZ + fractPosZ) * signZ; + } - if (!float.IsNaN(fractPosX) && !float.IsInfinity(fractPosX)) position.x = (intPosX + fractPosX) * signX; - if (!float.IsNaN(fractPosY) && !float.IsInfinity(fractPosY)) position.y = (intPosY + fractPosY) * signY; - if (!float.IsNaN(fractPosZ) && !float.IsInfinity(fractPosZ)) position.z = (intPosZ + fractPosZ) * signZ; - return position; } diff --git a/Plugins/Runtime/Resources/RealtimeCSG/Materials/Floor.mat b/Plugins/Runtime/Resources/RealtimeCSG/Materials/Floor.mat index ecca51624490e1a46f02b04b624c247bd5998e80..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 5104 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 literal 19212 zcmeHP3se)=7QGQPia-QKK{NqHZKW0eU&0(`)^Ta%iw7v>wh zKlTRTJa07o`Ecy@sK~(8Q2^LR8$NMWUy_*EphL9(s_0<)m(h&RH;04B&o@Ry&x#0- zcA7tH_N+OJ%74G`1pptgm-u-vXNI;O3(Be&ZCR_o9htRTU39a4N5 z&9}3$Np3Ej;P2;Gw`GUh?)do9<`J}U*kFZK!COu62MM%8rMuT+=^p$#k1dYa&HHXjaPN7$+Ohj_Lw6iu;!6l`$H#1Uakio<20i$eP?pomQ zOy$SiN}_pI()jELWT)(zmjqF&Q?gM6?&Y?n+szaHeFfK1nvpuMuEM&rVg~;`Lg`tH zhw@7H16D1n!zpxp0ZZ3TlH}>{ixnDA7+$63U?d~*oXPlQg zTuVS7H4spkL8s{3#S(UVafUop_u;rC1yF$FvK4a#{|fTjP?|OQVO9`j3o&VpU8N*P zQ?3$r0DC$@Ly_2}qHGZ=`snFydN_5mmFw6l?1ueMV%OU=cr z`u1xXx6C$YZr6Fb^J7x)5P@_rE6*G4$dW+18$9fCYSTMu4$RJ0349geOacPrH=4fM z6-YCONyP%>fl5@Qc;sp(g?#Xy9Zd9~& zM+P-cP1zBENL|PA^Tm_IoarP;A#IXt7Uj)%S4YXx%@dqM4vHz-YreII+G^aOo#L}$ zoOhq#B3HxDdAs{<51Ry{-=$3B?1kWWbSeod^;9BlHxEJZO>8OLRdi?}q7L7tUai~D zKS3?<3MJ8hSIQ)a?UgcqkzuA;(-SL|cHb%Ob}Czy>+K~($p%=%&`5ubKRRLd`v*`C z|Eg4uPhC?lK89ht@%zu__@&?Y<$BWL)HTKMr?%2n!Q3;rYoRA{@v6LXM zpyk$F=2W5}f?CBEZIbeMG!fdMl0$j~tyu|5XpYooQa~X?!l>iXK8S}WRO4p*b^}*> z3hF@Mc6I^u@!Sffd(}4{i$Dn$!55XydI?+go7Bn+sW0@HTau!$-dLq> zmg=^4y4mi7vYoKufxLU7do5EnS%N&YVzNh3Trx2K9X2c%uE^+rZ3z+vaxD?AE`n)0YP`0nkSXd=Eawkx{RV!)Y5ZvIPx`HETfxtGM2 z0$g$>^+f-lLPrCb%ALtTnk6Yk5&zbydoK?lD1V-Memh*k98ClZUJ$z2Z=Loi4As2l zz1?q34T!A^7CW?U+NEpWA9M^~w_YN`=*UDI({gCgspzz|V@Ob}28xQU(RaDMwpt@nJ{GSCmVe#){W6pED z{%rbRjW0~v!agHc-;vO1o*RKOxrmQwWz=(@oks+`7GVdiZYzy+Ac`d zkU}qrQC;StI_ZasAW6LRMq8%4jAU7@B1j;CQpEfQZdcy0mavr#t#nkYs}R&Tfm%`W zJfxf_SMqBTWsvS}nIPNZK7!k6>k{~jo%K%v{jicy`Y}Q1vk<>H@09f)h(Zi?symol z;dW+ga~1_sHPiIJF_wK|rf%Ec=`eK@J9d&;kl+~eJ??$nVroG)J!(8@qHFGRFl}sr zO3bRgx`3s0V*&D3>4}OGKGkdFh%!);B4>^zQe9EKq(B_2wc92v!?jogtuo(`IiM=F zPCHgK;&v-(aZkhsxTEukK<@mk21uaFaEr5QK#7V(^@Kzo=7=yb)tZ|si17;572yB` zdGcXq?7ZGro^o~b&2_t4#wTPnl1vo6%7EDph;E=e=ye3h{J|$n<%6aGcl+r70<}I~O z2;I$>-8ZnI<*CzZR#iXMh&>*x-4jCGTonFkc;H7^E=C^LRBQLU#(foiWQBumSybj> z+KoPovH`H*Ux<)RQ|YT39l)xT;1o%X-(e6kBxqsMX#=kMF60wLI8YIG(0TmYlOe<@ zS25(Ed4`N#QMcQ9A~qH$e1s*BioWaO0nB7bwh|`P_O-!!U8|DtEwD6EQ?D(d3Hl~# zGN>G{D+mW5xESG7Ow`neT4j9HCHq5o{KnMnTartJ{B?b?m|~serfQVb0(-f zhzU~NH++`_6iqp6aYRTYBx?v3k0k;|eY*K5+i$)zYf0`?tlWt&T>Jm)1aH<p58=i47DRe7-(G7@$z_lL>yr`l$3oh{Lfd#-qo64Wm+aQ<%IkS zg<{Iw@lBhH$LyU|Hj|KCgNnNNsPi!mVx2VU9%(nQT=SJpWc-*rh_2~_BRV}iDv5pA1%Z9$j~FG zbq=w?aP?F(?wzZo;P|HV*T?L^XvjA#=2?fgs|)7)1rrsCp`jd&TOKl)Jm zI@%lrW1aM~d_v%3M`H|ocBh);HMhUjZ+!>80^7M}~IA6aJLS+CfX`-e- z>l}#@;>|=&CTbeGgIFeN`b$$2?gi)j1|p-(lQM?=Ao2fkw_ty;;arHfV9y;3XhwEF z&F$Bu0}bRnixE!ci3F-?N#~PYIB%1XwgC0BvpJaOzqcIIkHFc#Kf%Ei_G%SFq- zA6QL&o99mg8zT;eq_Jk|+ZaJ}?sZvadioQH%j^bYo${TJdGpAAas4|&O~KyR!w~*< ztJ1?d6&4s`@V&gMKfz=XHXQIbxy8sm^PI^d{P&CmREADME last updated March 4th, 2022 +README last updated June 9th, 2022 diff --git a/README.md.meta b/README.md.meta new file mode 100644 index 0000000..dd123cf --- /dev/null +++ b/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6cf88510b97e70d46ae01d5e906a15a8 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Readme.meta b/Readme.meta new file mode 100644 index 0000000..ef67649 --- /dev/null +++ b/Readme.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 43eab678fc07d0341bab03b1bc17147f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Readme/Images.meta b/Readme/Images.meta new file mode 100644 index 0000000..3135152 --- /dev/null +++ b/Readme/Images.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fecc954b06bddad4895bac125b25e963 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Readme/Images/house_view.png.meta b/Readme/Images/house_view.png.meta new file mode 100644 index 0000000..b400444 --- /dev/null +++ b/Readme/Images/house_view.png.meta @@ -0,0 +1,98 @@ +fileFormatVersion: 2 +guid: 48600d27b94721b4a95f5ea75e59408d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMasterTextureLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: