Beispiel #1
0
        static void ExportAllToObj()
        {
            CSGModel activeCSGModel = CSGModel.GetActiveCSGModel();

            if (activeCSGModel != null)
            {
                activeCSGModel.ExportOBJ(false);
            }
        }
Beispiel #2
0
        static void Rebuild()
        {
            CSGModel activeCSGModel = CSGModel.GetActiveCSGModel();

            if (activeCSGModel != null)
            {
                activeCSGModel.Build(false, false);
            }
        }
Beispiel #3
0
        void OnDrawGizmosSelected()
        {
            CSGModel parentCSGModel = GetCSGModel() as CSGModel;

            if (parentCSGModel != null)
            {
                // Ensure Edit Mode is on
                parentCSGModel.EditMode = true;
            }
        }
Beispiel #4
0
 protected override void OnItemClick(Object selectedObject)
 {
     if (selectedObject is Material)
     {
         CSGModel activeModel = CSGModel.GetActiveCSGModel();
         if (activeModel != null)
         {
             SurfaceEditor surfaceEditor = (SurfaceEditor)activeModel.GetTool(MainMode.Face);
             surfaceEditor.SetSelectionMaterial((Material)selectedObject);
         }
     }
 }
Beispiel #5
0
        public override void OnGUI()
        {
            var model = CSGModel.GetActiveCSGModel();

            if (model)
            {
                Toolbar.CSGModel = model;
                Toolbar.OnTopToolbarGUI(0);

                window1?.Invoke();
                window2?.Invoke();
            }
        }
        public static GUIStyle GetTextFieldStyle1()
        {
            GUIStyle style = new GUIStyle(EditorStyles.textField);

            if (textFieldTexture1 == null)
            {
                textFieldTexture1 = UnityEditor.AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Gizmos/TextField.png") as Texture2D;
            }
            style.normal.background  = textFieldTexture1;
            style.normal.textColor   = Color.white;
            style.focused.background = textFieldTexture1;
            style.focused.textColor  = Color.white;
            return(style);
        }
        //	    public static Material GetMarqueeBorderMaterial()
        //	    {
        //	        if (marqueeBorderMaterial == null)
        //	        {
        //	            marqueeBorderMaterial = new Material(Shader.Find("Transparent/Diffuse"));
        //	        }
        //	        return marqueeBorderMaterial;
        //	    }
        //
        //	    public static Material GetMarqueeFillMaterial()
        //	    {
        //	        if (marqueeFillMaterial == null)
        //	        {
        //	            marqueeFillMaterial = new Material(Shader.Find("Transparent/Diffuse"));
        //	        }
        //	        return marqueeFillMaterial;
        //	    }

        public static Material GetExcludedMaterial()
        {
            if (excludedTexture == null)
            {
                excludedTexture = UnityEditor.AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Internal/Excluded.png") as Texture2D;
            }
            if (excludedMaterial == null)
            {
                excludedMaterial                  = new Material(Shader.Find("SabreCSG/SeeExcluded"));
                excludedMaterial.hideFlags        = HideFlags.HideAndDontSave;
                excludedMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
                excludedMaterial.mainTexture      = excludedTexture;
            }
            return(excludedMaterial);
        }
Beispiel #8
0
        public static VertexColorWindow CreateAndShow(CSGModel csgModel, SurfaceEditor surfaceEditor)
        {
            VertexColorWindow window = EditorWindow.GetWindow <VertexColorWindow>(true, "Vertex Colors", true);

            window.surfaceEditor = surfaceEditor;
            window.csgModel      = csgModel;

            // By setting both sizes to the same, even the resize cursor hover is automatically disabled
            window.minSize = WINDOW_SIZE;
            window.maxSize = WINDOW_SIZE;

            window.Show();

            return(window);
        }
Beispiel #9
0
        void OnGUI()
        {
            if (surfaceEditor == null || csgModel == null)
            {
                // Link to face tool has been lost, so attempt to reacquire
                CSGModel[] csgModels = FindObjectsOfType <CSGModel>();

                // Build the first csg model that is currently being edited
                for (int i = 0; i < csgModels.Length; i++)
                {
                    if (csgModels[i].EditMode)
                    {
                        csgModel      = csgModels[i];
                        surfaceEditor = csgModels[i].GetTool(MainMode.Face) as SurfaceEditor;
                        break;
                    }
                }

                // If it's still null
                if (surfaceEditor == null || csgModel == null)
                {
                    GUILayout.Label("No active CSG Model");
                    return;
                }
            }

            GUILayout.Label("Set Vertex Colors", SabreGUILayout.GetTitleStyle());

            Color sourceColor = surfaceEditor.GetColor();

            Color newColor = EditorGUILayout.ColorField(sourceColor);

            if (newColor != sourceColor)
            {
                surfaceEditor.SetSelectionColor(newColor);
            }

            // Preset color buttons
            GUILayout.BeginHorizontal();
            for (int i = 0; i < PRESET_COLORS.Length; i++)
            {
                if (SabreGUILayout.ColorButton(PRESET_COLORS[i]))
                {
                    surfaceEditor.SetSelectionColor(PRESET_COLORS[i]);
                }
            }
            GUILayout.EndHorizontal();
        }
Beispiel #10
0
        private void SetVisualMaterial(Material lastVisualMaterial, Material newVisualMaterial)
        {
            // EnsureDefaultMaterialSet hasn't had a chance to run yet, so make sure we have a solid material reference
            if (newVisualMaterial == null)
            {
                CSGModel csgModel = (CSGModel)target;
                newVisualMaterial = csgModel.GetDefaultFallbackMaterial();
            }

            // Update the built renderers that use the old material, also update source brush polygons
            UpdateVisualMaterial(lastVisualMaterial, newVisualMaterial);

            defaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
            // Update the last build's default material because we don't need to build again
            lastBuildDefaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
        }
Beispiel #11
0
        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            CSGModel csgModel = (CSGModel)target;

            if (GUILayout.Button("Export OBJ"))
            {
                csgModel.ExportOBJ();
            }
            BuildMetrics buildMetrics = csgModel.BuildMetrics;

            GUILayout.Label("Vertices: " + buildMetrics.TotalVertices);
            GUILayout.Label("Triangles: " + buildMetrics.TotalTriangles);
            GUILayout.Label("Meshes: " + buildMetrics.TotalMeshes);
            GUILayout.Label("Build Time: " + buildMetrics.BuildTime.ToString());
        }
Beispiel #12
0
        private void UpdateVisualMaterial(Material oldMaterial, Material newMaterial)
        {
            // If the material has changed and the new material is not null
            if (newMaterial != oldMaterial && newMaterial != null)
            {
                CSGModel csgModel = (CSGModel)target;

                // Update the built mesh renderers that use the old material
                Transform meshGroup = csgModel.GetMeshGroupTransform();

                if (meshGroup != null)
                {
                    MeshRenderer[] meshRenderers = meshGroup.GetComponentsInChildren <MeshRenderer>();
                    for (int i = 0; i < meshRenderers.Length; i++)
                    {
                        if (meshRenderers[i].sharedMaterial == oldMaterial)
                        {
                            meshRenderers[i].sharedMaterial = newMaterial;
                        }
                    }
                }

                // Update all the polygons in the source brushes
                List <Brush> brushes = csgModel.GetBrushes();
                for (int i = 0; i < brushes.Count; i++)
                {
                    if (brushes[i] != null) // Make sure the tracked brush still exists
                    {
                        Polygon[] polygons = brushes[i].GetPolygons();
                        for (int j = 0; j < polygons.Length; j++)
                        {
                            // If the polygon uses the old material (as an override)
                            if (polygons[j].Material == oldMaterial)
                            {
                                // Set the polygon to null, this removes the material override which gives consistent behaviour
                                polygons[j].Material = null;
                            }
                        }
                    }
                }
            }
        }
Beispiel #13
0
        /// <summary>
        /// Loads an object from a path, or if the object is already loaded returns it
        /// </summary>
        /// <param name="sabrePath">Path local to the SabreCSG folder</param>
        /// <returns></returns>
        private static Object LoadObject(string sabrePath)
        {
            bool found = false;

            Object loadedObject = null;

            // First of all see if there's a cached record
            if (loadedObjects.ContainsKey(sabrePath))
            {
                found        = true;
                loadedObject = loadedObjects[sabrePath];

                // Now make sure the cached record actually points to something
                if (loadedObject != null)
                {
                    return(loadedObject);
                }
            }

            // Failed to load from cache, so load it from the Asset Database
            loadedObject = AssetDatabase.LoadMainAssetAtPath(Path.Combine(CSGModel.GetSabreCSGPath(), sabrePath));
            if (loadedObject != null)
            {
                if (found)
                {
                    // A cache record was found but empty, so set the existing record to the newly loaded object
                    loadedObjects[sabrePath] = loadedObject;
                }
                else
                {
                    // We know that it's not already in the cache, so add it to the end
                    loadedObjects.Add(sabrePath, loadedObject);
                }
            }
            return(loadedObject);
        }
Beispiel #14
0
        public override void OnInspectorGUI()
        {
            CSGModel csgModel = (CSGModel)target;

            // Ensure the default material is set
            csgModel.EnsureDefaultMaterialSet();

            DrawDefaultInspector();

            this.serializedObject.Update();
            using (NamedVerticalScope scope = new NamedVerticalScope("Build Settings"))
            {
                scope.WikiLink = "Build-Settings";

                EditorGUIUtility.fieldWidth = 0;
                EditorGUIUtility.labelWidth = 160;

                EditorGUILayout.PropertyField(generateCollisionMeshesProperty, new GUIContent("Generate Collision Meshes"));
                EditorGUILayout.PropertyField(generateTangentsProperty, new GUIContent("Generate Tangents"));

                EditorGUILayout.PropertyField(generateLightmapUVsProperty, new GUIContent("Generate Lightmap UVs"));
                EditorGUIUtility.labelWidth = 125;

                GUI.enabled           = generateLightmapUVsProperty.boolValue;
                EditorGUI.indentLevel = 1;
                EditorGUILayout.PropertyField(unwrapAngleErrorProperty, new GUIContent("Unwrap Angle Error"));
                EditorGUILayout.PropertyField(unwrapAreaErrorProperty, new GUIContent("Unwrap Area Error"));
                EditorGUILayout.PropertyField(unwrapHardAngleProperty, new GUIContent("Unwrap Hard Angle"));
                EditorGUILayout.PropertyField(unwrapPackMarginProperty, new GUIContent("Unwrap Pack Margin"));
                EditorGUI.indentLevel       = 0;
                EditorGUIUtility.labelWidth = 0;
                GUI.enabled = true;

                EditorGUILayout.PropertyField(shadowCastingModeProperty, new GUIContent("Shadow Casting Mode"));
                EditorGUILayout.PropertyField(reflectionProbeUsageProperty, new GUIContent("Reflection Probes"));

                // Experimental build settings to enable features that are not yet completely stable
                GUILayout.Label("Experimental", EditorStyles.boldLabel);
                EditorGUI.indentLevel = 1;

                EditorGUILayout.PropertyField(optimizeGeometryProperty, new GUIContent("Optimize Geometry"));
                EditorGUILayout.PropertyField(saveMeshesAsAssetsProperty, new GUIContent("Save Meshes As Assets"));
                EditorGUI.indentLevel = 0;
            }

            using (new NamedVerticalScope("Default Material"))
            {
                PhysicMaterial lastPhysicsMaterial = defaultPhysicsMaterialProperty.objectReferenceValue as PhysicMaterial;

                EditorGUI.BeginChangeCheck();
                EditorGUILayout.PropertyField(defaultPhysicsMaterialProperty, new GUIContent("Default Physics Material"));
                if (EditorGUI.EndChangeCheck())
                {
                    PhysicMaterial newPhysicsMaterial = defaultPhysicsMaterialProperty.objectReferenceValue as PhysicMaterial;

                    // Update the built mesh colliders that use the old material
                    UpdatePhysicsMaterial(lastPhysicsMaterial, newPhysicsMaterial);
                }

                // Track the last visual material, so that if the user changes it we can update built renderers instantly
                Material lastVisualMaterial = defaultVisualMaterialProperty.objectReferenceValue as Material;

                EditorGUI.BeginChangeCheck();
                EditorGUILayout.PropertyField(defaultVisualMaterialProperty, new GUIContent("Default Visual Material"));
                if (EditorGUI.EndChangeCheck())
                {
                    // User has changed the material, so grab the new material
                    Material newVisualMaterial = defaultVisualMaterialProperty.objectReferenceValue as Material;
                    // EnsureDefaultMaterialSet hasn't had a chance to run yet, so make sure we have a solid material reference
                    if (newVisualMaterial == null)
                    {
                        newVisualMaterial = csgModel.GetDefaultFallbackMaterial();
                        defaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
                    }

                    // Update the built renderers that use the old material, also update source brush polygons
                    UpdateVisualMaterial(lastVisualMaterial, newVisualMaterial);

                    // Update the last build's default material because we don't need to build again
                    lastBuildDefaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
                }

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Lit Texture (No Tint)"))
                {
                    Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_Map.mat") as Material;
                    SetVisualMaterial(lastVisualMaterial, newVisualMaterial);
                }
                if (GUILayout.Button("Lit Vertex Tint"))
                {
                    Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_LitWithTint.mat") as Material;
                    SetVisualMaterial(lastVisualMaterial, newVisualMaterial);
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Unlit Vertex Color"))
                {
                    Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_VertexColor.mat") as Material;
                    SetVisualMaterial(lastVisualMaterial, newVisualMaterial);
                }
                if (GUILayout.Button("Lit Vertex Color"))
                {
                    Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_VertexColorLit.mat") as Material;
                    SetVisualMaterial(lastVisualMaterial, newVisualMaterial);
                }
                EditorGUILayout.EndHorizontal();
            }

            using (NamedVerticalScope scope = new NamedVerticalScope("Export"))
            {
                scope.WikiLink = "Build-Settings#exporting-obj-files";

                if (GUILayout.Button("Export All To OBJ"))
                {
                    csgModel.ExportOBJ(false);
                }

                if (GUILayout.Button("Export Selected To OBJ"))
                {
                    csgModel.ExportOBJ(true);
                }
            }

            using (new NamedVerticalScope("Import"))
            {
                GuiLayoutBeginImporterSection(SabreCSGResources.ImporterUnrealGoldTexture, "Unreal Gold Importer", "Henry de Jongh");

                importerUnrealGoldScale = EditorGUILayout.IntField("Scale", importerUnrealGoldScale);
                if (importerUnrealGoldScale < 1)
                {
                    importerUnrealGoldScale = 1;
                }

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Import Unreal Gold Map (*.t3d)"))
                {
                    try
                    {
                        string path = EditorUtility.OpenFilePanel("Import Unreal Gold Map", "", "t3d");
                        if (path.Length != 0)
                        {
                            EditorUtility.DisplayProgressBar("SabreCSG: Importing Unreal Gold Map", "Parsing Unreal Text File (*.t3d)...", 0.0f);
                            var importer = new Importers.UnrealGold.T3dImporter();
                            var map      = importer.Import(path);
                            Importers.UnrealGold.T3dMapConverter.Import(csgModel, map, importerUnrealGoldScale);
                        }
                    }
                    catch (Exception ex)
                    {
                        EditorUtility.ClearProgressBar();
                        EditorUtility.DisplayDialog("Unreal Gold Map Import", "An exception occurred while importing the map:\r\n" + ex.Message, "Ohno!");
                    }
                }
                if (GUILayout.Button("?", GUILayout.Width(16)))
                {
                    EditorUtility.DisplayDialog("Unreal Gold Importer", "This importer was created using Unreal Gold 227 (http://oldunreal.com/).\n\nImportant Notes:\n* It will try to find the materials in your project automatically. First it looks for the full name like 'PlayrShp.Ceiling.Hullwk' then the last word 'Hullwk'. The latter option could cause some false positives, try creating a material with the full name if this happens.\n* This importer requires you to place a massive additive cube around your whole level as Unreal Editor uses the subtractive workflow.\n\nKnown Issues:\n* Concave brushes may cause corruptions.", "Okay");
                }
                EditorGUILayout.EndHorizontal();
                GuiLayoutEndImporterSection();

                //
                EditorGUILayout.Space();
                //

                GuiLayoutBeginImporterSection(SabreCSGResources.ImporterImporterValveMapFormat2006Texture, "Source Engine 2006 Importer", "Henry de Jongh");

                EditorGUILayout.BeginHorizontal();
                if (GUILayout.Button("Import Source Engine Map (*.vmf)"))
                {
                    try
                    {
                        string path = EditorUtility.OpenFilePanel("Import Source Engine Map", "", "vmf");
                        if (path.Length != 0)
                        {
                            EditorUtility.DisplayProgressBar("SabreCSG: Importing Source Engine Map", "Parsing Valve Map Format File (*.vmf)...", 0.0f);
                            var importer = new Importers.ValveMapFormat2006.VmfImporter();
                            var map      = importer.Import(path);
                            Importers.ValveMapFormat2006.VmfWorldConverter.Import(csgModel, map);
                        }
                    }
                    catch (Exception ex)
                    {
                        EditorUtility.ClearProgressBar();
                        EditorUtility.DisplayDialog("Source Engine Map Import", "An exception occurred while importing the map:\r\n" + ex.Message, "Ohno!");
                    }
                }

                if (GUILayout.Button("?", GUILayout.Width(16)))
                {
                    EditorUtility.DisplayDialog("Source Engine 2006 Importer", "This importer was created using Source SDK maps and Hammer 4.1.\n\nImportant Notes:\n* It will try to find the materials in your project automatically. First it looks for the full name with forward slashes '/' replaced by periods '.' like 'BRICK.BRICKFLOOR001A' then the last word 'BRICKFLOOR001A'. The latter option could cause some false positives, try creating a material with the full name if this happens.", "Okay");
                }
                EditorGUILayout.EndHorizontal();

                GuiLayoutEndImporterSection();
            }

            using (new NamedVerticalScope("Stats"))
            {
                BuildMetrics buildMetrics = csgModel.BuildMetrics;

                GUILayout.Label("Vertices: " + buildMetrics.TotalVertices);
                GUILayout.Label("Triangles: " + buildMetrics.TotalTriangles);
                GUILayout.Label("Meshes: " + buildMetrics.TotalMeshes);
                GUILayout.Label("Build Time: " + buildMetrics.BuildTime.ToString());
            }

            // Make sure any serialize property changes are committed to the underlying Unity Object
            bool anyApplied = this.serializedObject.ApplyModifiedProperties();

            if (anyApplied)
            {
                // Make sure that nothing else is included in the Undo, as an immediate rebuild may take place and
                // we don't want the rebuild's lastBuildSettings being included in the undo step
                Undo.IncrementCurrentGroup();
            }
        }
        public override void Invalidate(bool polygonsChanged)
        {
            if (!gameObject.activeInHierarchy)
            {
                return;
            }

            // Make sure there is a mesh filter on this object
            MeshFilter   meshFilter   = gameObject.AddOrGetComponent <MeshFilter>();
            MeshRenderer meshRenderer = gameObject.AddOrGetComponent <MeshRenderer>();

            // Used to use mesh colliders for ray collision, but not any more so clean them up
            MeshCollider[] meshColliders = GetComponents <MeshCollider>();

            if (meshColliders.Length > 0)
            {
                for (int i = 0; i < meshColliders.Length; i++)
                {
                    DestroyImmediate(meshColliders[i]);
                }
            }

            bool requireRegen = false;

            // If the cached ID hasn't been set or we mismatch
            if (cachedInstanceID == 0 ||
                gameObject.GetInstanceID() != cachedInstanceID)
            {
                requireRegen     = true;
                cachedInstanceID = gameObject.GetInstanceID();
            }


            Mesh renderMesh = meshFilter.sharedMesh;

            if (requireRegen)
            {
                renderMesh = new Mesh();
            }

            if (polygons != null)
            {
                List <int> polygonIndices;
                PolygonFactory.GenerateMeshFromPolygons(polygons, ref renderMesh, out polygonIndices);
            }

            if (mode == CSGMode.Subtract)
            {
                PolygonFactory.Invert(ref renderMesh);
            }
            // Displace the triangles for display along the normals very slightly (this is so we can overlay built
            // geometry with semi-transparent geometry and avoid depth fighting)
            PolygonFactory.Displace(ref renderMesh, 0.001f);

            meshFilter.sharedMesh = renderMesh;

            meshRenderer.receiveShadows    = false;
            meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;

            meshFilter.hideFlags   = HideFlags.NotEditable;          // | HideFlags.HideInInspector;
            meshRenderer.hideFlags = HideFlags.NotEditable;          // | HideFlags.HideInInspector;

#if UNITY_EDITOR
            meshRenderer.sharedMaterial = UnityEditor.AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Materials/" + this.mode.ToString() + ".mat") as Material;
#endif
            isBrushConvex = PolygonFactory.IsMeshConvex(polygons);

            if (polygonsChanged)
            {
                RecalculateBrushCache();
            }

            UpdateVisibility();

            objectVersionSerialized++;
            objectVersionUnserialized = objectVersionSerialized;
        }
Beispiel #16
0
        public static void PreferencesGUI()
        {
            //			Event.current.GetTypeForControl
            //
            //			if(Event.current.type == EventType.KeyDown)
            //			{
            //				cachedEvent = new Event(Event.current);
            ////				this.Repaint();
            //			}
            //
            //			GUILayout.TextField("");
            //
            //			if(cachedEvent != null)
            //			{
            //				GUILayout.Label(cachedEvent.ToString());
            //			}
            //			else
            //			{
            //				GUILayout.Label("No event");
            //			}

            GUILayout.Space(10);

            bool newHideGridInPerspective = GUILayout.Toggle(CurrentSettings.HideGridInPerspective, "Hide grid in perspective scene views");

            if (newHideGridInPerspective != CurrentSettings.HideGridInPerspective)
            {
                SceneView.RepaintAll();
                CurrentSettings.HideGridInPerspective = newHideGridInPerspective;
            }

            CurrentSettings.OverrideFlyCamera = GUILayout.Toggle(CurrentSettings.OverrideFlyCamera, "Linear fly camera");

            EditorGUI.BeginChangeCheck();
            CurrentSettings.ShowExcludedPolygons = GUILayout.Toggle(CurrentSettings.ShowExcludedPolygons, "Show excluded polygons");
            if (EditorGUI.EndChangeCheck())
            {
                // What's shown in the SceneView has potentially changed, so force it to repaint
                SceneView.RepaintAll();
            }

            EditorGUI.BeginChangeCheck();
            CurrentSettings.ShowBrushesAsWireframes = GUILayout.Toggle(CurrentSettings.ShowBrushesAsWireframes, "Show brushes as wireframes");
            if (EditorGUI.EndChangeCheck())
            {
                // What's shown in the SceneView has potentially changed, so force it to repaint
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }

            EditorGUI.BeginChangeCheck();
            CurrentSettings.ShowBrushBoundsGuideLines = GUILayout.Toggle(CurrentSettings.ShowBrushBoundsGuideLines, "Show brush bounds guide lines");
            if (EditorGUI.EndChangeCheck())
            {
                // What's shown in the SceneView has potentially changed, so force it to repaint
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }

            EditorGUILayout.Space();
            EditorGUI.indentLevel = 1;
            EditorGUILayout.LabelField("Developer Options", EditorStyles.boldLabel);
            EditorGUI.indentLevel = 0;
            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck();
            CurrentSettings.ShowHiddenGameObjectsInHierarchy = GUILayout.Toggle(CurrentSettings.ShowHiddenGameObjectsInHierarchy, "Show hidden game objects in hierarchy");
            if (EditorGUI.EndChangeCheck())
            {
                // What's shown in the SceneView has potentially changed, so force it to repaint
                CSGModel.RebuildAllVolumes();
                SceneView.RepaintAll();
            }

            GUILayout.Space(10);

            if (GUILayout.Button("Change key mappings"))
            {
                Selection.activeObject = KeyMappings.Instance;
                // Show inspector
                EditorApplication.ExecuteMenuItem("Window/Inspector");
            }
            //			CurrentSettings.ReducedHandleThreshold = GUILayout.Toggle(CurrentSettings.ReducedHandleThreshold, "Reduced handle threshold");

            GUILayout.Space(20);

            GUIStyle style = SabreGUILayout.GetForeStyle();

            style.wordWrap = true;
            GUILayout.Label("Runtime CSG is a new experimental feature which allows you to create, alter and build brushes at runtime in your built applications.", style);
            BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
            string           defines          = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
            List <string>    definesSplit     = defines.Split(';').ToList();
            bool             enabled          = definesSplit.Contains(RUNTIME_CSG_DEFINE);

            if (enabled)
            {
                if (GUILayout.Button("Disable Runtime CSG (Experimental)"))
                {
                    definesSplit.Remove(RUNTIME_CSG_DEFINE);
                    defines = string.Join(";", definesSplit.ToArray());
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
                }
            }
            else
            {
                if (GUILayout.Button("Enable Runtime CSG (Experimental)"))
                {
                    if (!definesSplit.Contains(RUNTIME_CSG_DEFINE))
                    {
                        definesSplit.Add(RUNTIME_CSG_DEFINE);
                    }
                    defines = string.Join(";", definesSplit.ToArray());
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
                }
            }

            GUILayout.FlexibleSpace();

            GUILayout.Label("SabreCSG Version " + CSGModel.VERSION_STRING, SabreGUILayout.GetForeStyle());
        }
Beispiel #17
0
        void OnSelectionChanged()
        {
            bool anyCSGObjectsSelected = false;
            bool anyNonCSGSelected     = false;

            List <CSGModel> foundModels = new List <CSGModel>();
            Dictionary <CSGModel, List <UnityEngine.Object> > selectedBrushes = new Dictionary <CSGModel, List <UnityEngine.Object> >();

            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                PrimitiveBrush primitiveBrush = Selection.gameObjects[i].GetComponent <PrimitiveBrush>();
                CSGModel       csgModel       = Selection.gameObjects[i].GetComponent <CSGModel>();

                if (primitiveBrush != null)
                {
                    csgModel = primitiveBrush.GetCSGModel() as CSGModel;

                    if (!foundModels.Contains(csgModel))
                    {
                        foundModels.Add(csgModel);
                        selectedBrushes[csgModel] = new List <UnityEngine.Object>();
                    }

                    selectedBrushes[csgModel].Add(primitiveBrush.gameObject);
                }

                if (csgModel != null)
                {
                    anyCSGObjectsSelected = true;

                    if (!foundModels.Contains(csgModel))
                    {
                        foundModels.Add(csgModel);
                        selectedBrushes[csgModel] = new List <UnityEngine.Object>();
                    }
                }
                else
                {
                    CSGModel[] parentCSGModels = Selection.gameObjects[i].GetComponentsInParent <CSGModel>(true);
                    if (parentCSGModels.Length > 0)
                    {
                        csgModel = parentCSGModels[0];

                        if (Selection.gameObjects[i].GetComponent <MeshFilter>() != null ||
                            Selection.gameObjects[i].GetComponent <MeshCollider>() != null)
                        {
                            anyNonCSGSelected = true;
                        }
                        else
                        {
                            anyCSGObjectsSelected = true;

                            if (!foundModels.Contains(csgModel))
                            {
                                foundModels.Add(csgModel);
                                selectedBrushes[csgModel] = new List <UnityEngine.Object>();
                            }
                        }
                    }
                    else
                    {
                        anyNonCSGSelected = true;
                    }
                }
            }

            if (anyCSGObjectsSelected)
            {
                CSGModel activeModel = null;
                if (foundModels.Count == 1)
                {
                    if (!foundModels[0].EditMode)
                    {
                        foundModels[0].EditMode = true;
                    }
                    activeModel = foundModels[0];
                }
                else
                {
                    bool anyActive = false;

                    for (int i = 0; i < foundModels.Count; i++)
                    {
                        if (foundModels[i].EditMode)
                        {
                            anyActive   = true;
                            activeModel = foundModels[i];
                            break;
                        }
                    }

                    if (!anyActive)
                    {
                        foundModels[0].EditMode = true;
                        activeModel             = foundModels[0];
                    }
                }

                if (anyNonCSGSelected && activeModel != null)
                {
                    deferredSelection = selectedBrushes[activeModel].ToArray();
                }
            }
            else if (anyNonCSGSelected)
            {
                EditMode = false;
            }


            if (EditMode)
            {
                // Walk backwards until we find the last selected brush
                for (int i = Selection.gameObjects.Length - 1; i >= 0; i--)
                {
                    Brush brush = Selection.gameObjects[i].GetComponent <Brush>();

                    if (brush != null)
                    {
                        lastSelectedBrush = brush;
                        break;
                    }
                }
            }
        }
 public CSGModel GetCSGModel()
 {
     if (parentCsgModel == null)
     {
         parentCsgModel = transform.GetComponentInParent<CSGModel>();
     }
     return parentCsgModel;
 }
 static string GetPluginPath()
 {
     return(CSGModel.GetSabreCSGPath() + "Scripts/SabreCSG.Core.dll");
 }
Beispiel #20
0
        private static void OnBottomToolbarGUI(int windowID)
        {
            GUILayout.BeginHorizontal();

            GUIStyle createBrushStyle = new GUIStyle(EditorStyles.toolbarButton);

            createBrushStyle.fixedHeight = 20;
            if (GUI.Button(new Rect(0, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCubeTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Cube);
            }

            if (GUI.Button(new Rect(30, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonPrismTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Prism);
            }

            //if(GUI.Button(new Rect(60,0, 30, createBrushStyle.fixedHeight), "", createBrushStyle))
            //{
            //}

            if (GUI.Button(new Rect(60, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonStairsTexture, createBrushStyle))
            {
                CreateCompoundBrush <StairBrush>();
            }

            if (GUI.Button(new Rect(90, 0, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCurvedStairsTexture, createBrushStyle))
            {
                CreateCompoundBrush <CurvedStairBrush>();
            }

            GUILayout.Space(92 + 30);
#if DEBUG_SABRECSG_PERF
            // For debugging frame rate
            GUILayout.Label(((int)(1 / csgModel.CurrentFrameDelta)).ToString(), SabreGUILayout.GetLabelStyle());
#endif

            if (SabreGUILayout.Button("Rebuild"))
            {
                csgModel.Build(false, false);
            }

            if (SabreGUILayout.Button("Force Rebuild"))
            {
                csgModel.Build(true, false);
            }

            GUI.color = Color.white;

            if (csgModel.AutoRebuild)
            {
                GUI.color = Color.green;
            }
            csgModel.AutoRebuild = SabreGUILayout.Toggle(csgModel.AutoRebuild, "Auto Rebuild");
            GUI.color            = Color.white;

            GUILayout.Label(csgModel.BuildMetrics.BuildMetaData.ToString(), SabreGUILayout.GetForeStyle(), GUILayout.Width(140));

            bool lastBrushesHidden = CurrentSettings.BrushesHidden;
            if (lastBrushesHidden)
            {
                GUI.color = Color.red;
            }
            CurrentSettings.BrushesHidden = SabreGUILayout.Toggle(CurrentSettings.BrushesHidden, "Brushes Hidden");
            if (CurrentSettings.BrushesHidden != lastBrushesHidden)
            {
                // Has changed
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }
            GUI.color = Color.white;


            bool lastMeshHidden = CurrentSettings.MeshHidden;
            if (lastMeshHidden)
            {
                GUI.color = Color.red;
            }
            CurrentSettings.MeshHidden = SabreGUILayout.Toggle(CurrentSettings.MeshHidden, "Mesh Hidden");
            if (CurrentSettings.MeshHidden != lastMeshHidden)
            {
                // Has changed
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }

            GUI.color = Color.white;


            if (GUILayout.Button("Grid " + CurrentSettings.GridMode.ToString(), EditorStyles.toolbarDropDown, GUILayout.Width(90)))
            {
                GenericMenu menu = new GenericMenu();

                string[] names = Enum.GetNames(typeof(GridMode));

                for (int i = 0; i < names.Length; i++)
                {
                    GridMode value    = (GridMode)Enum.Parse(typeof(GridMode), names[i]);
                    bool     selected = false;
                    if (CurrentSettings.GridMode == value)
                    {
                        selected = true;
                    }
                    menu.AddItem(new GUIContent(names[i]), selected, OnSelectedGridOption, value);
                }

                menu.DropDown(gridRect);
            }

            if (Event.current.type == EventType.Repaint)
            {
                gridRect       = GUILayoutUtility.GetLastRect();
                gridRect.width = 100;
            }

            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            // Line Two
            GUILayout.BeginHorizontal();

            if (GUI.Button(new Rect(0, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonCylinderTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Cylinder);
            }

            if (GUI.Button(new Rect(30, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonSphereTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Sphere);
            }

            if (GUI.Button(new Rect(60, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), SabreCSGResources.ButtonConeTexture, createBrushStyle))
            {
                CreatePrimitiveBrush(PrimitiveBrushType.Cone);
            }

            //if (GUI.Button(new Rect(60, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), "", createBrushStyle))
            //{
            //}

            if (GUI.Button(new Rect(90, createBrushStyle.fixedHeight, 30, createBrushStyle.fixedHeight), "...", createBrushStyle))
            {
                GenericMenu menu = new GenericMenu();

                List <Type> compoundBrushTypes = CompoundBrush.FindAllInAssembly();
                for (int i = 0; i < compoundBrushTypes.Count; i++)
                {
                    menu.AddItem(new GUIContent(compoundBrushTypes[i].Name), false, CreateCompoundBrush, compoundBrushTypes[i]);
                }

                menu.DropDown(new Rect(60, createBrushStyle.fixedHeight, 100, createBrushStyle.fixedHeight));
            }

            GUILayout.Space(92 + 30);

            // Display brush count
            GUILayout.Label(csgModel.BrushCount.ToStringWithSuffix(" brush", " brushes"), SabreGUILayout.GetLabelStyle());
//			CurrentSettings.GridMode = (GridMode)EditorGUILayout.EnumPopup(CurrentSettings.GridMode, EditorStyles.toolbarPopup, GUILayout.Width(80));

            if (Selection.activeGameObject != null)
            {
                BrushBase        primaryBrush = Selection.activeGameObject.GetComponent <BrushBase>();
                List <BrushBase> brushes      = new List <BrushBase>();
                for (int i = 0; i < Selection.gameObjects.Length; i++)
                {
                    BrushBase brush = Selection.gameObjects[i].GetComponent <BrushBase>();
                    if (brush != null)
                    {
                        brushes.Add(brush);
                    }
                }
                if (primaryBrush != null)
                {
                    CSGMode brushMode = (CSGMode)EditorGUILayout.EnumPopup(primaryBrush.Mode, EditorStyles.toolbarPopup, GUILayout.Width(80));
                    if (brushMode != primaryBrush.Mode)
                    {
                        bool anyChanged = false;

                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush To " + brushMode);
                            brush.Mode = brushMode;
                            anyChanged = true;
                        }
                        if (anyChanged)
                        {
                            // Need to update the icon for the csg mode in the hierarchy
                            EditorApplication.RepaintHierarchyWindow();
                        }
                    }


                    bool[] noCSGStates = brushes.Select(brush => brush.IsNoCSG).Distinct().ToArray();
                    bool   isNoCSG     = (noCSGStates.Length == 1) ? noCSGStates[0] : false;

                    bool newIsNoCSG = SabreGUILayout.ToggleMixed(noCSGStates, "NoCSG", GUILayout.Width(53));


                    bool[] collisionStates = brushes.Select(item => item.HasCollision).Distinct().ToArray();
                    bool   hasCollision    = (collisionStates.Length == 1) ? collisionStates[0] : false;

                    bool newHasCollision = SabreGUILayout.ToggleMixed(collisionStates, "Collision", GUILayout.Width(53));


                    bool[] visibleStates = brushes.Select(item => item.IsVisible).Distinct().ToArray();
                    bool   isVisible     = (visibleStates.Length == 1) ? visibleStates[0] : false;

                    bool newIsVisible = SabreGUILayout.ToggleMixed(visibleStates, "Visible", GUILayout.Width(53));

                    if (newIsNoCSG != isNoCSG)
                    {
                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush NoCSG Mode");
                            brush.IsNoCSG = newIsNoCSG;
                        }
                        // Tell the brushes that they have changed and need to recalc intersections
                        foreach (BrushBase brush in brushes)
                        {
                            brush.Invalidate(true);
                        }

                        EditorApplication.RepaintHierarchyWindow();
                    }
                    if (newHasCollision != hasCollision)
                    {
                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush Collision Mode");
                            brush.HasCollision = newHasCollision;
                        }
                        // Tell the brushes that they have changed and need to recalc intersections
                        foreach (BrushBase brush in brushes)
                        {
                            brush.Invalidate(true);
                        }
                    }
                    if (newIsVisible != isVisible)
                    {
                        foreach (BrushBase brush in brushes)
                        {
                            Undo.RecordObject(brush, "Change Brush Visible Mode");
                            brush.IsVisible = newIsVisible;
                        }
                        // Tell the brushes that they have changed and need to recalc intersections
                        foreach (BrushBase brush in brushes)
                        {
                            brush.Invalidate(true);
                        }
                        if (newIsVisible == false)
                        {
                            csgModel.NotifyPolygonsRemoved();
                        }
                    }
                }
            }

            GUILayout.Space(10);

            // Position snapping UI
            CurrentSettings.PositionSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.PositionSnappingEnabled, "Pos Snapping");
            CurrentSettings.PositionSnapDistance    = EditorGUILayout.FloatField(CurrentSettings.PositionSnapDistance, GUILayout.Width(50));

            if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft))
            {
                CurrentSettings.ChangePosSnapDistance(.5f);
            }
            if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight))
            {
                CurrentSettings.ChangePosSnapDistance(2f);
            }

            // Rotation snapping UI
            CurrentSettings.AngleSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.AngleSnappingEnabled, "Ang Snapping");
            CurrentSettings.AngleSnapDistance    = EditorGUILayout.FloatField(CurrentSettings.AngleSnapDistance, GUILayout.Width(50));

            if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft))
            {
                if (CurrentSettings.AngleSnapDistance > 15)
                {
                    CurrentSettings.AngleSnapDistance -= 15;
                }
                else
                {
                    CurrentSettings.AngleSnapDistance -= 5;
                }
            }
            if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight))
            {
                if (CurrentSettings.AngleSnapDistance >= 15)
                {
                    CurrentSettings.AngleSnapDistance += 15;
                }
                else
                {
                    CurrentSettings.AngleSnapDistance += 5;
                }
            }

            GUILayout.FlexibleSpace();

            if (SabreGUILayout.Button("Prefs"))
            {
                SabreCSGPreferences.CreateAndShow();
            }

            if (SabreGUILayout.Button("Disable"))
            {
                Selection.activeGameObject = null;
                csgModel.EditMode          = false;
            }

            GUILayout.EndHorizontal();
        }
Beispiel #21
0
        static void OnViewMenuGUI(int windowID)
        {
            float left_pad = 90f;

            EditorGUIUtility.labelWidth = 118f;

            GUILayout.Space(4);

            GUILayout.BeginHorizontal();
            GUILayout.Label("Viewport Settings", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            bool lastBrushesHidden = CurrentSettings.BrushesHidden;

            CurrentSettings.BrushesHidden = EditorGUILayout.Toggle(
                new GUIContent("Hide Brushes", "Hotkey: " + KeyMappings.Instance.ToggleBrushesHidden),
                CurrentSettings.BrushesHidden
                );
            if (CurrentSettings.BrushesHidden != lastBrushesHidden)
            {
                // Has changed
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }
            GUILayout.EndHorizontal();

            bool lastMeshHidden = CurrentSettings.MeshHidden;

            CurrentSettings.MeshHidden = EditorGUILayout.Toggle("Hide Meshes", CurrentSettings.MeshHidden);
            if (CurrentSettings.MeshHidden != lastMeshHidden)
            {
                // Has changed
                CSGModel.UpdateAllBrushesVisibility();
                SceneView.RepaintAll();
            }

            GUILayout.Space(10);

            GUILayout.BeginHorizontal();
            GUILayout.Label("Grid Settings", EditorStyles.boldLabel);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("Grid type", EditorStyles.label);
            GUILayout.FlexibleSpace();

            GridMode lastMode = CurrentSettings.GridMode;

            CurrentSettings.GridMode = (GridMode)EditorGUILayout.EnumPopup(CurrentSettings.GridMode, GUILayout.Width(left_pad));
            if (CurrentSettings.GridMode != lastMode)
            {
                OnSelectedGridOption(CurrentSettings.GridMode);
            }
            GUILayout.EndHorizontal();

            // Projected grid
            bool lastProjectedGridEnabled = CurrentSettings.ProjectedGridEnabled;

            CurrentSettings.ProjectedGridEnabled = EditorGUILayout.Toggle(
                new GUIContent("Projected Grid", "Hotkey: " + KeyMappings.Instance.ToggleProjectedGrid.Replace("#", "Shift+")),
                CurrentSettings.ProjectedGridEnabled
                );
            if (CurrentSettings.ProjectedGridEnabled != lastProjectedGridEnabled)
            {
                SceneView.RepaintAll();
            }
            if (Event.current.type == EventType.Repaint)
            {
                gridRect       = GUILayoutUtility.GetLastRect();
                gridRect.width = 100;
            }

            // Position snapping UI
            CurrentSettings.PositionSnappingEnabled = EditorGUILayout.Toggle(
                new GUIContent("Grid snapping", "Hotkey: " + KeyMappings.Instance.TogglePosSnapping.Replace("#", "Shift+")),
                CurrentSettings.PositionSnappingEnabled
                );

            // Position snapping UI
            CurrentSettings.AngleSnappingEnabled = EditorGUILayout.Toggle(
                new GUIContent("Rotation snapping", "Hotkey: " + KeyMappings.Instance.ToggleAngSnapping.Replace("#", "Shift+")),
                CurrentSettings.AngleSnappingEnabled
                );

            // Rotation snapping UI
            GUILayout.BeginHorizontal();
            GUILayout.Label(new GUIContent(
                                "Rotation size",
                                "Hotkeys: " + KeyMappings.Instance.DecreaseAngSnapping.Replace("#", "Shift+") + "  " + KeyMappings.Instance.IncreaseAngSnapping.Replace("#", "Shift+")
                                ), EditorStyles.label);
            GUILayout.FlexibleSpace();

            // CurrentSettings.AngleSnappingEnabled = SabreGUILayout.Toggle(CurrentSettings.AngleSnappingEnabled, "Ang Snapping");
            CurrentSettings.AngleSnapDistance = EditorGUILayout.FloatField(CurrentSettings.AngleSnapDistance, GUILayout.Width(50));

            if (SabreGUILayout.Button("-", EditorStyles.miniButtonLeft))
            {
                if (CurrentSettings.AngleSnapDistance > 15)
                {
                    CurrentSettings.AngleSnapDistance -= 15;
                }
                else
                {
                    CurrentSettings.AngleSnapDistance -= 5;
                }
            }
            if (SabreGUILayout.Button("+", EditorStyles.miniButtonRight))
            {
                if (CurrentSettings.AngleSnapDistance >= 15)
                {
                    CurrentSettings.AngleSnapDistance += 15;
                }
                else
                {
                    CurrentSettings.AngleSnapDistance += 5;
                }
            }
            GUILayout.EndHorizontal();
        }
Beispiel #22
0
        public override void OnInspectorGUI()
        {
            CSGModel csgModel = (CSGModel)target;

            // Ensure the default material is set
            csgModel.EnsureDefaultMaterialSet();

            DrawDefaultInspector();

            this.serializedObject.Update();
            GUILayout.Label("Build Settings", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(generateCollisionMeshesProperty, new GUIContent("Generate Collision Meshes"));
            EditorGUILayout.PropertyField(generateTangentsProperty, new GUIContent("Generate Tangents"));
            EditorGUILayout.PropertyField(generateLightmapUVsProperty, new GUIContent("Generate Lightmap UVs"));

            GUI.enabled           = generateLightmapUVsProperty.boolValue;
            EditorGUI.indentLevel = 1;
            EditorGUILayout.PropertyField(unwrapAngleErrorProperty, new GUIContent("Unwrap Angle Error"));
            EditorGUILayout.PropertyField(unwrapAreaErrorProperty, new GUIContent("Unwrap Area Error"));
            EditorGUILayout.PropertyField(unwrapHardAngleProperty, new GUIContent("Unwrap Hard Angle"));
            EditorGUILayout.PropertyField(unwrapPackMarginProperty, new GUIContent("Unwrap Pack Margin"));
            EditorGUI.indentLevel = 0;
            GUI.enabled           = true;

            PhysicMaterial lastPhysicsMaterial = defaultPhysicsMaterialProperty.objectReferenceValue as PhysicMaterial;

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(defaultPhysicsMaterialProperty, new GUIContent("Default Physics Material"));
            if (EditorGUI.EndChangeCheck())
            {
                PhysicMaterial newPhysicsMaterial = defaultPhysicsMaterialProperty.objectReferenceValue as PhysicMaterial;

                // Update the built mesh colliders that use the old material
                UpdatePhysicsMaterial(lastPhysicsMaterial, newPhysicsMaterial);
            }

            // Track the last visual material, so that if the user changes it we can update built renderers instantly
            Material lastVisualMaterial = defaultVisualMaterialProperty.objectReferenceValue as Material;

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(defaultVisualMaterialProperty, new GUIContent("Default Visual Material"));
            if (EditorGUI.EndChangeCheck())
            {
                // User has changed the material, so grab the new material
                Material newVisualMaterial = defaultVisualMaterialProperty.objectReferenceValue as Material;
                // EnsureDefaultMaterialSet hasn't had a chance to run yet, so make sure we have a solid material reference
                if (newVisualMaterial == null)
                {
                    newVisualMaterial = csgModel.GetDefaultFallbackMaterial();
                    defaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
                }

                // Update the built renderers that use the old material, also update source brush polygons
                UpdateVisualMaterial(lastVisualMaterial, newVisualMaterial);

                // Update the last build's default material because we don't need to build again
                lastBuildDefaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
            }

            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Lit Texture (No Tint)"))
            {
                Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_Map.mat") as Material;

                // EnsureDefaultMaterialSet hasn't had a chance to run yet, so make sure we have a solid material reference
                if (newVisualMaterial == null)
                {
                    newVisualMaterial = csgModel.GetDefaultFallbackMaterial();
                }

                // Update the built renderers that use the old material, also update source brush polygons
                UpdateVisualMaterial(lastVisualMaterial, newVisualMaterial);

                defaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
                // Update the last build's default material because we don't need to build again
                lastBuildDefaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
            }
            if (GUILayout.Button("Lit Vertex Tint"))
            {
                Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_LitWithTint.mat") as Material;

                // EnsureDefaultMaterialSet hasn't had a chance to run yet, so make sure we have a solid material reference
                if (newVisualMaterial == null)
                {
                    newVisualMaterial = csgModel.GetDefaultFallbackMaterial();
                }

                // Update the built renderers that use the old material, also update source brush polygons
                UpdateVisualMaterial(lastVisualMaterial, newVisualMaterial);

                defaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
                // Update the last build's default material because we don't need to build again
                lastBuildDefaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
            }
            if (GUILayout.Button("Unlit Vertex Color"))
            {
                Material newVisualMaterial = AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Resources/Materials/Default_VertexColor.mat") as Material;

                // EnsureDefaultMaterialSet hasn't had a chance to run yet, so make sure we have a solid material reference
                if (newVisualMaterial == null)
                {
                    newVisualMaterial = csgModel.GetDefaultFallbackMaterial();
                }

                // Update the built renderers that use the old material, also update source brush polygons
                UpdateVisualMaterial(lastVisualMaterial, newVisualMaterial);

                defaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
                // Update the last build's default material because we don't need to build again
                lastBuildDefaultVisualMaterialProperty.objectReferenceValue = newVisualMaterial;
            }
            EditorGUILayout.EndHorizontal();
            // Divider line
            GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));

            if (GUILayout.Button("Export OBJ"))
            {
                csgModel.ExportOBJ();
            }
            BuildMetrics buildMetrics = csgModel.BuildMetrics;

            GUILayout.Label("Vertices: " + buildMetrics.TotalVertices);
            GUILayout.Label("Triangles: " + buildMetrics.TotalTriangles);
            GUILayout.Label("Meshes: " + buildMetrics.TotalMeshes);
            GUILayout.Label("Build Time: " + buildMetrics.BuildTime.ToString());

            // Make sure any serialize property changes are committed to the underlying Unity Object
            bool anyApplied = this.serializedObject.ApplyModifiedProperties();

            if (anyApplied)
            {
                // Make sure that nothing else is included in the Undo, as an immediate rebuild may take place and
                // we don't want the rebuild's lastBuildSettings being included in the undo step
                Undo.IncrementCurrentGroup();
            }
        }
        public static void PreferencesGUI()
        {
            //			Event.current.GetTypeForControl
            //
            //			if(Event.current.type == EventType.KeyDown)
            //			{
            //				cachedEvent = new Event(Event.current);
            ////				this.Repaint();
            //			}
            //
            //			GUILayout.TextField("");
            //
            //			if(cachedEvent != null)
            //			{
            //				GUILayout.Label(cachedEvent.ToString());
            //			}
            //			else
            //			{
            //				GUILayout.Label("No event");
            //			}

            GUILayout.Space(10);

            bool newHideGridInPerspective = GUILayout.Toggle(CurrentSettings.HideGridInPerspective, "Hide grid in perspective scene views");

            if (newHideGridInPerspective != CurrentSettings.HideGridInPerspective)
            {
                SceneView.RepaintAll();
                CurrentSettings.HideGridInPerspective = newHideGridInPerspective;
            }

            CurrentSettings.AlwaysSnapToCurrentGrid = GUILayout.Toggle(CurrentSettings.AlwaysSnapToCurrentGrid, new GUIContent("Always snap to current grid size", "When position snapping is enabled, you can press " + KeyMappings.Instance.SnapSelectionToCurrentGrid + " to snap movement to the current grid size or tick this option to have it always on."));

            CurrentSettings.OverrideFlyCamera = GUILayout.Toggle(CurrentSettings.OverrideFlyCamera, "Linear fly camera");

            EditorGUILayout.Space();
            using (new SabreEditorGUI.IndentLevelScope()) {
                EditorGUILayout.LabelField("Experimental Options", EditorStyles.boldLabel);
            }
            EditorGUILayout.Space();

            CurrentSettings.VertexPaintToolEnabled = GUILayout.Toggle(CurrentSettings.VertexPaintToolEnabled, "Vertex paint tool");

            EditorGUILayout.Space();
            using (new SabreEditorGUI.IndentLevelScope()) {
                EditorGUILayout.LabelField("Developer Options", EditorStyles.boldLabel);
            }
            EditorGUILayout.Space();

            EditorGUI.BeginChangeCheck();
            CurrentSettings.ShowHiddenGameObjectsInHierarchy = GUILayout.Toggle(CurrentSettings.ShowHiddenGameObjectsInHierarchy, "Show hidden game objects in hierarchy");
            if (EditorGUI.EndChangeCheck())
            {
                // What's shown in the SceneView has potentially changed, so force it to repaint
                CSGModel.RebuildAllVolumes();
                SceneView.RepaintAll();
            }

            GUILayout.Space(10);

            if (GUILayout.Button("Change key mappings"))
            {
                Selection.activeObject = KeyMappings.Instance;
                // Show inspector
                EditorApplication.ExecuteMenuItem("Window/Inspector");
            }
            //			CurrentSettings.ReducedHandleThreshold = GUILayout.Toggle(CurrentSettings.ReducedHandleThreshold, "Reduced handle threshold");

            GUILayout.Space(20);

            GUIStyle style = SabreGUILayout.GetForeStyle();

            style.wordWrap = true;
            GUILayout.Label("Runtime CSG is a new experimental feature which allows you to create, alter and build brushes at runtime in your built applications.", style);
            BuildTargetGroup buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
            string           defines          = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
            List <string>    definesSplit     = defines.Split(';').ToList();
            bool             enabled          = definesSplit.Contains(RUNTIME_CSG_DEFINE);

            if (enabled)
            {
                if (GUILayout.Button("Disable Runtime CSG (Experimental)"))
                {
                    definesSplit.Remove(RUNTIME_CSG_DEFINE);
                    defines = string.Join(";", definesSplit.ToArray());
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
                }
            }
            else
            {
                if (GUILayout.Button("Enable Runtime CSG (Experimental)"))
                {
                    if (!definesSplit.Contains(RUNTIME_CSG_DEFINE))
                    {
                        definesSplit.Add(RUNTIME_CSG_DEFINE);
                    }
                    defines = string.Join(";", definesSplit.ToArray());
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
                }
            }

            GUILayout.Space(20);
            GUILayout.Label("Debug mode executes additional code for verbose error checking. Used by SabreCSG developers.", style);
            buildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup;
            defines          = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
            definesSplit     = defines.Split(';').ToList();
            enabled          = definesSplit.Contains(SABRE_CSG_DEBUG_DEFINE);
            if (enabled)
            {
                if (GUILayout.Button("Disable Debug Mode (Recommended)"))
                {
                    definesSplit.Remove(SABRE_CSG_DEBUG_DEFINE);
                    defines = string.Join(";", definesSplit.ToArray());
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
                }
            }
            else
            {
                if (GUILayout.Button("Enable Debug Mode (Not Recommended)"))
                {
                    if (!definesSplit.Contains(SABRE_CSG_DEBUG_DEFINE))
                    {
                        definesSplit.Add(SABRE_CSG_DEBUG_DEFINE);
                    }
                    defines = string.Join(";", definesSplit.ToArray());
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
                }
            }

            GUILayout.FlexibleSpace();

            GUILayout.Label("SabreCSG Version " + CSGModel.VERSION_STRING, SabreGUILayout.GetForeStyle());
        }
 public static Material GetVertexMaterial()
 {
     if (vertexMaterial == null)
     {
         Shader shader = Shader.Find("SabreCSG/Handle");
         vertexMaterial                  = new Material(shader);
         vertexMaterial.hideFlags        = HideFlags.HideAndDontSave;
         vertexMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
         vertexMaterial.mainTexture      = UnityEditor.AssetDatabase.LoadMainAssetAtPath(CSGModel.GetSabreCSGPath() + "Gizmos/CircleGizmo8x8.png") as Texture;
     }
     return(vertexMaterial);
 }