public override void OnInspectorGUI() { //Get our stamper m_stamper = (Stamper)target; //Init editor utils m_editorUtils.Initialize(); //Set up the box style if (m_boxStyle == null) { m_boxStyle = new GUIStyle(GUI.skin.box); m_boxStyle.normal.textColor = GUI.skin.label.normal.textColor; m_boxStyle.fontStyle = FontStyle.Bold; m_boxStyle.alignment = TextAnchor.UpperLeft; } //Setup the wrap style if (m_wrapStyle == null) { m_wrapStyle = new GUIStyle(GUI.skin.label); m_wrapStyle.wordWrap = true; } //Draw the intro m_editorUtils.DrawIntro("Stamper", "The stamper allows you to stamp features into your terrain. Click here to see a tutorial.", "http://www.procedural-worlds.com/gaia/tutorials/stamper-introduction/"); //Disable if spawning if (m_stamper.m_stampComplete != true && !m_stamper.m_cancelStamp) { GUI.enabled = false; } EditorGUI.BeginChangeCheck(); GUILayout.BeginVertical("Operations:", m_boxStyle); GUILayout.Space(20); Texture2D feature = (Texture2D)EditorGUILayout.ObjectField(GetLabel("Stamp Preview"), m_stamper.m_stampPreviewImage, typeof(Texture2D), false); GaiaResource resources = (GaiaResource)EditorGUILayout.ObjectField(GetLabel("Resources"), m_stamper.m_resources, typeof(GaiaResource), false); Gaia.GaiaConstants.FeatureOperation operation = (Gaia.GaiaConstants.FeatureOperation)EditorGUILayout.EnumPopup(GetLabel("Operation Type"), m_stamper.m_stampOperation); float stencilHeight = m_stamper.m_stencilHeight; if (operation == GaiaConstants.FeatureOperation.StencilHeight) { stencilHeight = EditorGUILayout.Slider(GetLabel("Stencil Height"), m_stamper.m_stencilHeight, -1000f, 1000f); } float blendStrength = m_stamper.m_blendStrength; if (operation == GaiaConstants.FeatureOperation.BlendHeight) { blendStrength = EditorGUILayout.Slider(GetLabel("Blend Strength"), m_stamper.m_blendStrength, 0f, 1f); } //GUILayout.Label(stamper.m_feature, GUILayout.Width(200f), GUILayout.Height(200f) ); AnimationCurve heightModifier = EditorGUILayout.CurveField(GetLabel("Transform Height"), m_stamper.m_heightModifier); int smoothIterations = m_stamper.m_smoothIterations = EditorGUILayout.IntSlider(GetLabel("Smooth Stamp"), m_stamper.m_smoothIterations, 0, 10); bool normaliseStamp = EditorGUILayout.Toggle(GetLabel("Normalise Stamp"), m_stamper.m_normaliseStamp); bool invertStamp = EditorGUILayout.Toggle(GetLabel("Invert Stamp"), m_stamper.m_invertStamp); GUILayout.EndVertical(); GUILayout.BeginVertical("Position, Rotate and Scale:", m_boxStyle); GUILayout.Space(20); //GUILayout.Label("Operation:", EditorStyles.boldLabel); float x = EditorGUILayout.Slider(GetLabel("Position X"), m_stamper.m_x, m_minX, m_maxX); float y = m_stamper.m_y; if (!m_stamper.m_stickBaseToGround) { y = EditorGUILayout.Slider(GetLabel("Position Y"), m_stamper.m_y, m_minY, m_maxY); } float z = EditorGUILayout.Slider(GetLabel("Position Z"), m_stamper.m_z, m_minZ, m_maxZ); float rotation = EditorGUILayout.Slider(GetLabel("Rotation"), m_stamper.m_rotation, -180f, 180f); float width = EditorGUILayout.Slider(GetLabel("Width"), m_stamper.m_width, 0.1f, 200f); float height = EditorGUILayout.Slider(GetLabel("Height"), m_stamper.m_height, 0.1f, 100f); float baseLevel = EditorGUILayout.Slider(GetLabel("Base Level"), m_stamper.m_baseLevel, 0f, 1f); bool stickBaseToGround = EditorGUILayout.Toggle(GetLabel("Ground Base"), m_stamper.m_stickBaseToGround); bool stampBase = EditorGUILayout.Toggle(GetLabel("Stamp Base"), m_stamper.m_drawStampBase); bool showBase = EditorGUILayout.Toggle(GetLabel("Show Base"), m_stamper.m_showBase); GUILayout.EndVertical(); GUILayout.BeginVertical("Masks:", m_boxStyle); GUILayout.Space(20); //GUILayout.Label("Masks:", EditorStyles.boldLabel); AnimationCurve distanceMask = EditorGUILayout.CurveField(GetLabel("Distance Mask"), m_stamper.m_distanceMask); Gaia.GaiaConstants.ImageFitnessFilterMode areaMaskMode = (Gaia.GaiaConstants.ImageFitnessFilterMode)EditorGUILayout.EnumPopup(GetLabel("Area Mask"), m_stamper.m_areaMaskMode); Texture2D imageMask = m_stamper.m_imageMask; bool imageMaskInvert = m_stamper.m_imageMaskInvert; bool imageMaskNormalise = m_stamper.m_imageMaskNormalise; bool imageMaskFlip = m_stamper.m_imageMaskFlip; float noiseMaskSeed = m_stamper.m_noiseMaskSeed; int noiseMaskOctaves = m_stamper.m_noiseMaskOctaves; float noiseMaskPersistence = m_stamper.m_noiseMaskPersistence; float noiseMaskFrequency = m_stamper.m_noiseMaskFrequency; float noiseMaskLacunarity = m_stamper.m_noiseMaskLacunarity; float noiseZoom = m_stamper.m_noiseZoom; int imageMaskSmoothIterations = m_stamper.m_imageMaskSmoothIterations; if (areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageAlphaChannel || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageBlueChannel || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageGreenChannel || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageGreyScale || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageRedChannel) { imageMask = (Texture2D)EditorGUILayout.ObjectField(GetLabel("Image Mask"), m_stamper.m_imageMask, typeof(Texture2D), false); } else if (areaMaskMode == GaiaConstants.ImageFitnessFilterMode.PerlinNoise || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.RidgedNoise || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.BillowNoise) { noiseMaskSeed = EditorGUILayout.Slider(GetLabel("Noise Seed"), noiseMaskSeed, 0f, 65000f); noiseMaskOctaves = EditorGUILayout.IntSlider(GetLabel("Octaves"), noiseMaskOctaves, 1, 12); noiseMaskPersistence = EditorGUILayout.Slider(GetLabel("Persistence"), noiseMaskPersistence, 0f, 1f); noiseMaskFrequency = EditorGUILayout.Slider(GetLabel("Frequency"), noiseMaskFrequency, 0f, 1f); noiseMaskLacunarity = EditorGUILayout.Slider(GetLabel("Lacunarity"), noiseMaskLacunarity, 1.5f, 3.5f); noiseZoom = EditorGUILayout.Slider(GetLabel("Zoom"), noiseZoom, 1f, 1000f); } if (areaMaskMode != GaiaConstants.ImageFitnessFilterMode.None) { imageMaskSmoothIterations = EditorGUILayout.IntSlider(GetLabel("Smooth Mask"), m_stamper.m_imageMaskSmoothIterations, 0, 20); imageMaskNormalise = EditorGUILayout.Toggle(GetLabel("Normalise Mask"), m_stamper.m_imageMaskNormalise); imageMaskInvert = EditorGUILayout.Toggle(GetLabel("Invert Mask"), m_stamper.m_imageMaskInvert); imageMaskFlip = EditorGUILayout.Toggle(GetLabel("Flip Mask"), m_stamper.m_imageMaskFlip); } GUILayout.EndVertical(); GUILayout.BeginVertical("Helpers:", m_boxStyle); GUILayout.Space(20); //GUILayout.Label("Helpers:", EditorStyles.boldLabel); if (m_stamper.m_resources != null) { EditorGUILayout.LabelField("Sea Level", m_stamper.m_resources.m_seaLevel.ToString() + " m"); } bool showSeaLevel = EditorGUILayout.Toggle(GetLabel("Show Sea Level"), m_stamper.m_showSeaLevel); //Color gizmoColour = EditorGUILayout.ColorField(GetLabel("Gizmo Colour"), m_stamper.m_gizmoColour); bool alwaysShow = EditorGUILayout.Toggle(GetLabel("Always Show Stamper"), m_stamper.m_alwaysShow); bool showRulers = m_stamper.m_showRulers = EditorGUILayout.Toggle(GetLabel("Show Rulers"), m_stamper.m_showRulers); bool showTerrainHelper = m_stamper.m_showTerrainHelper = EditorGUILayout.Toggle(GetLabel("Show Terrain Helper"), m_stamper.m_showTerrainHelper); GUILayout.EndVertical(); //Check for changes, make undo record, make changes and let editor know we are dirty if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(m_stamper, "Made changes"); //Check to see if we need to load a new stamp if (feature != null) { if (m_stamper.m_stampPreviewImage == null) { m_stamper.m_stampPreviewImage = feature; m_stamper.LoadStamp(); m_stamper.FitToTerrain(); baseLevel = m_stamper.m_baseLevel; width = m_stamper.m_width; height = m_stamper.m_height; rotation = m_stamper.m_rotation; x = m_stamper.m_x; y = m_stamper.m_y; z = m_stamper.m_z; } else if (m_stamper.m_stampPreviewImage.GetInstanceID() != feature.GetInstanceID()) { m_stamper.m_stampPreviewImage = feature; m_stamper.LoadStamp(); baseLevel = m_stamper.m_baseLevel; } } //And invert it if (m_stamper.m_invertStamp != invertStamp) { m_stamper.m_invertStamp = invertStamp; m_stamper.InvertStamp(); } //And normalise it if (m_stamper.m_normaliseStamp != normaliseStamp) { m_stamper.m_normaliseStamp = normaliseStamp; if (normaliseStamp) { m_stamper.NormaliseStamp(); } else { m_stamper.LoadStamp(); baseLevel = m_stamper.m_baseLevel; } } m_stamper.m_heightModifier = heightModifier; m_stamper.m_drawStampBase = stampBase; m_stamper.m_stampOperation = operation; m_stamper.m_blendStrength = blendStrength; m_stamper.m_stencilHeight = stencilHeight; m_stamper.m_distanceMask = distanceMask; m_stamper.m_smoothIterations = smoothIterations; m_stamper.m_resources = resources; m_stamper.m_x = x; m_stamper.m_y = y; m_stamper.m_z = z; m_stamper.m_width = width; m_stamper.m_height = height; m_stamper.m_rotation = rotation; m_stamper.m_stickBaseToGround = stickBaseToGround; m_stamper.m_alwaysShow = alwaysShow; m_stamper.m_showSeaLevel = showSeaLevel; m_stamper.m_baseLevel = baseLevel; m_stamper.m_showBase = showBase; m_stamper.m_showRulers = showRulers; m_stamper.m_showTerrainHelper = showTerrainHelper; m_stamper.m_areaMaskMode = areaMaskMode; m_stamper.m_imageMask = imageMask; m_stamper.m_imageMaskInvert = imageMaskInvert; m_stamper.m_imageMaskNormalise = imageMaskNormalise; m_stamper.m_imageMaskFlip = imageMaskFlip; m_stamper.m_imageMaskSmoothIterations = imageMaskSmoothIterations; m_stamper.m_noiseMaskSeed = noiseMaskSeed; m_stamper.m_noiseMaskOctaves = noiseMaskOctaves; m_stamper.m_noiseMaskPersistence = noiseMaskPersistence; m_stamper.m_noiseMaskFrequency = noiseMaskFrequency; m_stamper.m_noiseMaskLacunarity = noiseMaskLacunarity; m_stamper.m_noiseZoom = noiseZoom; //Update the stamp calcs m_stamper.UpdateStamp(); EditorUtility.SetDirty(m_stamper); } //Terrain control if (showTerrainHelper) { GUILayout.BeginVertical("Terrain Helper", m_boxStyle); GUILayout.Space(20); if (GUILayout.Button(GetLabel("Show Terrain Utilities"))) { var export = EditorWindow.GetWindow <GaiaTerrainExplorerEditor>(false, "Terrain Utilities"); export.Show(); } GUILayout.BeginHorizontal(); if (GUILayout.Button(GetLabel("Flatten"))) { if (EditorUtility.DisplayDialog("Flatten Terrain tiles ?", "Are you sure you want to flatten all terrain tiles - this can not be undone ?", "Yes", "No")) { m_stamper.FlattenTerrain(); } } if (GUILayout.Button(GetLabel("Smooth"))) { if (EditorUtility.DisplayDialog("Smooth Terrain tiles ?", "Are you sure you want to smooth all terrain tiles - this can not be undone ?", "Yes", "No")) { m_stamper.SmoothTerrain(); } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button(GetLabel("Clear Trees"))) { if (EditorUtility.DisplayDialog("Clear Terrain trees ?", "Are you sure you want to clear all terrain trees - this can not be undone ?", "Yes", "No")) { m_stamper.ClearTrees(); } } if (GUILayout.Button(GetLabel("Clear Details"))) { if (EditorUtility.DisplayDialog("Clear Terrain details ?", "Are you sure you want to clear all terrain details - this can not be undone ?", "Yes", "No")) { m_stamper.ClearDetails(); } } GUILayout.EndHorizontal(); GUILayout.Space(5); GUILayout.EndVertical(); } //Regardless, re-enable the spawner controls GUI.enabled = true; //Display progress if (m_stamper.m_stampComplete != true && !m_stamper.m_cancelStamp) { GUILayout.BeginVertical("Stamp Controller", m_boxStyle); GUILayout.Space(20); GUILayout.BeginHorizontal(); if (GUILayout.Button(GetLabel("Cancel"))) { m_stamper.CancelStamp(); } GUILayout.EndHorizontal(); GUILayout.Space(5); GUILayout.EndVertical(); ProgressBar(string.Format("Progress ({0:0.0}%)", m_stamper.m_stampProgress * 100f), m_stamper.m_stampProgress); } else { //Stamp control GUILayout.BeginVertical("Stamp Controller", m_boxStyle); GUILayout.Space(20); if (!m_stamper.CanPreview()) { GUI.enabled = false; } GUILayout.BeginHorizontal(); if (GUILayout.Button(GetLabel("Ground"))) { m_stamper.AlignToGround(); m_stamper.UpdateStamp(); } if (GUILayout.Button(GetLabel("Fit To Terrain"))) { m_stamper.FitToTerrain(); m_stamper.UpdateStamp(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button(GetLabel("Preview"))) { m_stamper.TogglePreview(); } GUI.enabled = true; if (m_stamper.m_stampPreviewImage == null) { GUI.enabled = false; } if (GUILayout.Button(GetLabel("Stamp"))) { //Check that they have a single selected terrain if (Gaia.TerrainHelper.GetActiveTerrainCount() != 1) { EditorUtility.DisplayDialog("OOPS!", "You must have only one active terrain in order to use a Spawner. Please either add a terrain, or deactivate all but one terrain.", "OK"); } else { //Check that the centre of the terrain is at 0,0,0, and offer to move bool isCentred = true; Bounds b = new Bounds(); Terrain terrain = Gaia.TerrainHelper.GetActiveTerrain(); Gaia.TerrainHelper.GetTerrainBounds(terrain, ref b); if ((b.center.x != 0f) || (b.min.y != 0f) || (b.center.z != 0f)) { isCentred = false; if (EditorUtility.DisplayDialog("OOPS!", "The terrain must be centered at 0,0,0 for stamping to work properly. Would you like GAIA to move it for you? You will need to reposition your stamp after this to adjust for the movement. You can move the terrain back to its original position after you have finished with the stamper.", "OK", "Cancel")) { terrain.transform.position = new Vector3(b.extents.x * -1f, 0f, b.extents.z * -1f); } } if (isCentred) { //Check that they are not using terrain based mask - this can give unexpected results if (areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture0 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture1 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture2 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture3 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture4 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture5 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture6 || areaMaskMode == GaiaConstants.ImageFitnessFilterMode.TerrainTexture7 ) { //Do an alert and fix if necessary if (!m_stamper.IsFitToTerrain()) { if (EditorUtility.DisplayDialog("WARNING!", "This feature requires your stamp to be Fit To Terrain in order to guarantee correct placement.", "Stamp Anyway", "Cancel")) { m_stamper.Stamp(); } } else { m_stamper.Stamp(); } } else { m_stamper.Stamp(); } } } } GUI.enabled = true; if (m_stamper.CanRedo()) { if (GUILayout.Button(GetLabel("Redo"))) { m_stamper.Redo(); } } else { if (!m_stamper.CanUndo()) { GUI.enabled = false; } if (GUILayout.Button(GetLabel("Undo"))) { m_stamper.Undo(); } } GUI.enabled = true; GUILayout.EndHorizontal(); GUILayout.Space(5); GUILayout.EndVertical(); GUILayout.Space(5f); } }