388 lines
19 KiB
C#
388 lines
19 KiB
C#
#if UNITY_EDITOR
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace Gaia
|
|
{
|
|
/// <summary>
|
|
/// Flags passed to NoiseSettingsGUI.OnGUI. Used to specify which portions of the Noise Settings GUI to draw.
|
|
/// </summary>
|
|
public enum NoiseSettingsGUIFlags
|
|
{
|
|
Preview = (1 << 0),
|
|
Settings = (1 << 1),
|
|
All = ( ~0 ),
|
|
}
|
|
|
|
/// <summary>
|
|
/// Class used to draw the GUI for Noise Settings.
|
|
/// </summary>
|
|
public class NoiseSettingsGUI
|
|
{
|
|
/// <summary>
|
|
/// The SerializedObject for the NoiseSettings that this NoiseSettingsGUI instance is currently rendering the GUI for.
|
|
/// </summary>
|
|
public SerializedObject serializedNoise;
|
|
|
|
// noise settings properties
|
|
// noise settings properties
|
|
// noise settings properties
|
|
|
|
// coord space settings properties
|
|
private SerializedProperty transformSettings;
|
|
public SerializedProperty translation;
|
|
public SerializedProperty rotation;
|
|
public SerializedProperty scale;
|
|
public SerializedProperty flipScaleX;
|
|
public SerializedProperty flipScaleY;
|
|
public SerializedProperty flipScaleZ;
|
|
|
|
// domain settings properties
|
|
public SerializedProperty domainSettings;
|
|
public SerializedProperty noiseTypeName;
|
|
public SerializedProperty noiseTypeParams;
|
|
public SerializedProperty fractalTypeName;
|
|
public SerializedProperty fractalTypeParams;
|
|
|
|
// filter stack settings
|
|
// private SerializedProperty filterSettings;
|
|
// private FilterStackView m_filterStackView;
|
|
// private FilterStack m_filterStack;
|
|
// private SerializedObject m_serializedFilterStack;
|
|
// private bool m_showFilterStack;
|
|
|
|
private RenderTexture m_previewRT;
|
|
|
|
private bool m_noisePreviewIsLocked = false;
|
|
|
|
/// <summary>
|
|
/// The current NoiseSettings object that is associated with this instance of NoiseSettingsGUI.
|
|
/// </summary>
|
|
public NoiseSettings target = null;
|
|
|
|
|
|
public Rect rect;
|
|
|
|
public Spawner m_spawner;
|
|
|
|
/// <summary>
|
|
/// Sets up this instance of NoiseSettingsGUI with the specified NoiseSettings object.
|
|
/// GUI will be drawn for this NoiseSettings instance.
|
|
/// </summary>
|
|
/// <param name="noiseSettings"> The NoiseSettings instance for which GUI will be drawn </param>
|
|
public void Init(NoiseSettings noiseSettings)
|
|
{
|
|
Init(new SerializedObject(noiseSettings));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets up this instance of NoiseSettingsGUI with the specified SerializedObject containing an object reference
|
|
/// to a NoiseSettings instance. GUI will be drawn for this serialized NoiseSettings instance.
|
|
/// </summary>
|
|
/// <param name="serializedNoise"> A SerializedObject instance containing an object reference to a NoiseSettings object </param>
|
|
public void Init(SerializedObject serializedNoise)
|
|
{
|
|
this.serializedNoise = serializedNoise;
|
|
|
|
target = this.serializedNoise.targetObject as NoiseSettings;
|
|
|
|
// transform settings
|
|
transformSettings = this.serializedNoise.FindProperty("transformSettings");
|
|
translation = transformSettings.FindPropertyRelative("translation");
|
|
rotation = transformSettings.FindPropertyRelative("rotation");
|
|
scale = transformSettings.FindPropertyRelative("scale");
|
|
flipScaleX = transformSettings.FindPropertyRelative("flipScaleX");
|
|
flipScaleY = transformSettings.FindPropertyRelative("flipScaleY");
|
|
flipScaleZ = transformSettings.FindPropertyRelative("flipScaleZ");
|
|
|
|
// domain settings
|
|
domainSettings = this.serializedNoise.FindProperty("domainSettings");
|
|
noiseTypeName = domainSettings.FindPropertyRelative("noiseTypeName");
|
|
noiseTypeParams = domainSettings.FindPropertyRelative("noiseTypeParams");
|
|
fractalTypeName = domainSettings.FindPropertyRelative("fractalTypeName");
|
|
fractalTypeParams = domainSettings.FindPropertyRelative("fractalTypeParams");
|
|
|
|
// filter settings
|
|
// filterSettings = serializedNoise.FindProperty( "filterSettings" );
|
|
// m_filterStack = filterSettings.FindPropertyRelative( "filterStack" ).objectReferenceValue as FilterStack;
|
|
// m_serializedFilterStack = new SerializedObject( m_filterStack );
|
|
// m_filterStackView = new FilterStackView( new GUIContent( "Filters" ), m_serializedFilterStack, m_serializedFilterStack.targetObject as FilterStack );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renders the GUI for the NoiseSettings instance associated with this NoiseSettingsGUI instance.
|
|
/// </summary>
|
|
/// <param name="flags"> Flags specifying which portions of the GUI to draw </param>
|
|
public void OnGUI(NoiseSettingsGUIFlags flags = NoiseSettingsGUIFlags.All)
|
|
{
|
|
serializedNoise.Update();
|
|
|
|
if((flags & NoiseSettingsGUIFlags.Preview) != 0)
|
|
{
|
|
DrawPreviewTexture(256f,ref m_noisePreviewIsLocked);
|
|
}
|
|
|
|
if((flags & NoiseSettingsGUIFlags.Settings) != 0)
|
|
{
|
|
TerrainToolGUIHelper.DrawFoldout(transformSettings, Styles.transformSettings, TransformSettingsGUI);
|
|
TerrainToolGUIHelper.DrawFoldout(domainSettings, Styles.domainSettings, DomainSettingsGUI);
|
|
// TerrainToolGUIHelper.DrawFoldout(filterSettings, Styles.filterSettings, FilterSettingsGUI);
|
|
}
|
|
|
|
serializedNoise.ApplyModifiedProperties();
|
|
}
|
|
|
|
private void TransformSettingsGUI()
|
|
{
|
|
EditorGUILayout.PropertyField(translation);
|
|
EditorGUILayout.PropertyField(rotation);
|
|
EditorGUILayout.PropertyField(scale);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
{
|
|
EditorGUILayout.PrefixLabel(Styles.flipScale);
|
|
flipScaleX.boolValue = TerrainToolGUIHelper.ToggleButton(Styles.flipScaleX, flipScaleX.boolValue);
|
|
flipScaleY.boolValue = TerrainToolGUIHelper.ToggleButton(Styles.flipScaleY, flipScaleY.boolValue);
|
|
flipScaleZ.boolValue = TerrainToolGUIHelper.ToggleButton(Styles.flipScaleZ, flipScaleZ.boolValue);
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
|
|
private void DomainSettingsGUI()
|
|
{
|
|
noiseTypeName.stringValue = NoiseLib.NoiseTypePopup(Styles.noiseType, noiseTypeName.stringValue);
|
|
INoiseType noiseType = NoiseLib.GetNoiseTypeInstance(noiseTypeName.stringValue);
|
|
noiseTypeParams.stringValue = noiseType?.DoGUI(noiseTypeParams.stringValue);
|
|
|
|
fractalTypeName.stringValue = NoiseLib.FractalTypePopup(Styles.fractalType, fractalTypeName.stringValue);
|
|
IFractalType fractalType = NoiseLib.GetFractalTypeInstance(fractalTypeName.stringValue);
|
|
fractalTypeParams.stringValue = fractalType?.DoGUI(fractalTypeParams.stringValue);
|
|
}
|
|
|
|
private void DoMinMaxSliderInt(GUIContent label, SerializedProperty prop, SerializedProperty minMaxProp)
|
|
{
|
|
int min = minMaxProp.vector2IntValue.x;
|
|
int max = minMaxProp.vector2IntValue.y;
|
|
prop.intValue = TerrainToolGUIHelper.MinMaxSliderInt(label, prop.intValue, ref min, ref max);
|
|
minMaxProp.vector2IntValue = new Vector2Int(min, max);
|
|
}
|
|
|
|
private void DoMinMaxSlider(GUIContent label, SerializedProperty prop, SerializedProperty minMaxProp)
|
|
{
|
|
float min = minMaxProp.vector2Value.x;
|
|
float max = minMaxProp.vector2Value.y;
|
|
prop.floatValue = TerrainToolGUIHelper.MinMaxSlider(label, prop.floatValue, ref min, ref max);
|
|
minMaxProp.vector2Value = new Vector2(min, max);
|
|
}
|
|
|
|
// private void FilterSettingsGUI()
|
|
// {
|
|
// m_filterStackView.OnGUI();
|
|
// }
|
|
|
|
private void HandlePreviewTextureInput(Rect previewRect)
|
|
{
|
|
if(GUIUtility.hotControl != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 t = translation.vector3Value;
|
|
Vector3 r = rotation.vector3Value;
|
|
Vector3 s = scale.vector3Value;
|
|
|
|
EventType eventType = Event.current.type;
|
|
|
|
bool draggingPreview = Event.current.button == 0 &&
|
|
(eventType == EventType.MouseDown ||
|
|
eventType == EventType.MouseDrag);
|
|
|
|
Vector2 previewDims = new Vector2(previewRect.width, previewRect.height);
|
|
Vector2 abs = new Vector2(Mathf.Abs(s.x), Mathf.Abs(s.z));
|
|
|
|
if (Event.current.type == EventType.ScrollWheel)
|
|
{
|
|
abs += Vector2.one * .001f;
|
|
|
|
float scroll = Event.current.delta.y;
|
|
|
|
s.x += abs.x * scroll * .05f;
|
|
s.z += abs.y * scroll * .05f;
|
|
|
|
scale.vector3Value = s;
|
|
|
|
Event.current.Use();
|
|
GUI.changed = true;
|
|
}
|
|
else if (draggingPreview)
|
|
{
|
|
// change noise offset panning icon
|
|
Vector2 sign = new Vector2(-Mathf.Sign(s.x), Mathf.Sign(s.z));
|
|
Vector2 delta = Event.current.delta / previewDims * abs * sign;
|
|
Vector3 d3 = new Vector3(delta.x, 0, delta.y);
|
|
|
|
d3 = Quaternion.Euler( r ) * d3;
|
|
|
|
t += d3;
|
|
|
|
translation.vector3Value = t;
|
|
|
|
Event.current.Use();
|
|
GUI.changed = true;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renders an interactive Noise Preview along with tooltip icons and an optional Export button that opens a new ExportNoiseWindow.
|
|
/// A background image is also rendered behind the preview that takes up the entire width of the EditorWindow currently being drawn.
|
|
/// </summary>
|
|
/// <param name = "minSize"> Minimum size for the Preview </param>
|
|
/// <param name = "showExportButton"> Whether or not to render the Export button </param>
|
|
public void DrawPreviewTexture(float minSize, ref bool isLocked)
|
|
{
|
|
// Draw label with tooltip
|
|
//GUILayout.Label( Styles.noisePreview );
|
|
|
|
float padding = 4f;
|
|
float iconWidth = 40f;
|
|
int size = (int)Mathf.Min(minSize, EditorGUIUtility.currentViewWidth);
|
|
Rect currentRect = rect;
|
|
currentRect.y += EditorGUIUtility.singleLineHeight *2f;
|
|
Rect totalRect = new Rect(currentRect.x, currentRect.y, currentRect.width, size); //GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, size + padding * 2); // extra pixels for highlight border
|
|
|
|
Color prev = GUI.color;
|
|
GUI.color = new Color(.1f, .1f, .1f, 1f);
|
|
GUI.DrawTexture(totalRect, Texture2D.whiteTexture, ScaleMode.StretchToFill, false);
|
|
GUI.color = Color.white;
|
|
|
|
// draw info icon
|
|
// if(totalRect.Contains(Event.current.mousePosition))
|
|
{
|
|
Rect infoIconRect = new Rect( totalRect.x + padding, totalRect.y + padding, iconWidth, iconWidth );
|
|
GUI.Label( infoIconRect, Styles.infoIcon );
|
|
// GUI.Label( infoIconRect, Styles.noiseTooltip );
|
|
}
|
|
|
|
float buttonWidth = GUI.skin.button.CalcSize(Styles.buttonUnlocked).x;
|
|
float buttonHeight = EditorGUIUtility.singleLineHeight;
|
|
Rect lockButtonRect = new Rect(totalRect.x + padding, totalRect.y + padding * 2f + GUI.skin.button.CalcSize(Styles.infoIcon).y, buttonWidth, buttonHeight);
|
|
|
|
|
|
if (isLocked)
|
|
{
|
|
if (GUI.Button(lockButtonRect, Styles.buttonLocked))
|
|
{
|
|
isLocked = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GUI.Button(lockButtonRect, Styles.buttonUnlocked))
|
|
{
|
|
isLocked = true;
|
|
}
|
|
}
|
|
|
|
m_noisePreviewIsLocked = isLocked;
|
|
// draw export button
|
|
//Rect exportRect = new Rect( totalRect.xMax - buttonWidth - padding, totalRect.yMax - buttonHeight - padding, buttonWidth, buttonHeight );
|
|
//if(GUI.Button(exportRect, Styles.export))
|
|
//{
|
|
// serializedNoise.ApplyModifiedProperties();
|
|
// serializedNoise.Update();
|
|
|
|
// ExportNoiseWindow.ShowWindow( serializedNoise.targetObject as NoiseSettings );
|
|
//}
|
|
|
|
float safeSpace = Mathf.Max( iconWidth * 2, buttonWidth * 2 ) + padding * 4;
|
|
float minWidth = Mathf.Min( size, totalRect.width - safeSpace );
|
|
Rect previewRect = new Rect(totalRect.x + totalRect.width / 2 - minWidth / 2, totalRect.y + totalRect.height / 2 - minWidth / 2, minWidth, minWidth);
|
|
|
|
EditorGUIUtility.AddCursorRect(previewRect, MouseCursor.Pan);
|
|
|
|
if (previewRect.Contains(Event.current.mousePosition) && !isLocked)
|
|
{
|
|
serializedNoise.Update();
|
|
|
|
HandlePreviewTextureInput(previewRect);
|
|
|
|
serializedNoise.ApplyModifiedProperties();
|
|
}
|
|
|
|
if ( Event.current.type == EventType.Repaint )
|
|
{
|
|
// create preview RT here and keep until the next Repaint
|
|
if( m_previewRT != null )
|
|
{
|
|
RenderTexture.ReleaseTemporary( m_previewRT );
|
|
}
|
|
|
|
NoiseSettings noiseSettings = serializedNoise.targetObject as NoiseSettings;
|
|
|
|
m_previewRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.ARGB32);
|
|
RenderTexture tempRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.RFloat);
|
|
|
|
RenderTexture prevActive = RenderTexture.active;
|
|
|
|
NoiseUtils.Blit2D(noiseSettings, tempRT);
|
|
|
|
NoiseUtils.BlitPreview2D(tempRT, m_previewRT);
|
|
|
|
RenderTexture.active = prevActive;
|
|
|
|
GUI.DrawTexture(previewRect, m_previewRT, ScaleMode.ScaleToFit, false);
|
|
|
|
RenderTexture.ReleaseTemporary(tempRT);
|
|
}
|
|
|
|
GUI.color = prev;
|
|
}
|
|
|
|
static class Styles
|
|
{
|
|
public static GUIContent noiseSettings = EditorGUIUtility.TrTextContent("Noise Settings:");
|
|
public static GUIContent randomize = EditorGUIUtility.TrTextContent("Randomize");
|
|
public static GUIContent reset = EditorGUIUtility.TrTextContent("Reset");
|
|
public static GUIContent flipScale = EditorGUIUtility.TrTextContent("Flip Scale", "Flips the scale of the Noise Domain Space");
|
|
public static GUIContent flipScaleX = EditorGUIUtility.TrTextContent("X", "Flips the scale of the Noise Domain Space along the X-axis");
|
|
public static GUIContent flipScaleY = EditorGUIUtility.TrTextContent("Y", "Flips the scale of the Noise Domain Space along the Y-axis");
|
|
public static GUIContent flipScaleZ = EditorGUIUtility.TrTextContent("Z", "Flips the scale of the Noise Domain Space along the Z-axis");
|
|
public static GUIContent noiseType = EditorGUIUtility.TrTextContent("Noise Type", "The type of Noise to be used");
|
|
public static GUIContent fractalType = EditorGUIUtility.TrTextContent("Fractal Type", "The type of Fractal to be used when generating Noise");
|
|
public static GUIContent noisePreview;
|
|
public static GUIContent noiseTooltip = EditorGUIUtility.TrTextContent("",
|
|
"Scroll Mouse Wheel:\nZooms the preview in and out and changes the noise scale\n\n" +
|
|
"Left-mouse Drag:\nPans the noise field and changes the noise translation\n\n" +
|
|
"Color Key:\nCyan = negative noise values\nGrayscale = values between 0 and 1\nBlack = values are 0\nRed = Values greater than 1. Used for debugging texture normalization");
|
|
public static GUIContent seed = EditorGUIUtility.TrTextContent("Seed");
|
|
public static GUIContent domainSettings = EditorGUIUtility.TrTextContent("Domain Settings", "Settings governing the Noise Domain. This is specific to each Noise Type and Fractal Type implementation");
|
|
public static GUIContent transformSettings = EditorGUIUtility.TrTextContent("Transform Settings", "Settings governing the transformations applied to positions in the Noise Domain Space");
|
|
// public static GUIContent filterSettings = EditorGUIUtility.TrTextContent("Filter Settings");
|
|
public static GUIContent ridgePower = EditorGUIUtility.TrTextContent("Ridge Power");
|
|
public static GUIContent billowPower = EditorGUIUtility.TrTextContent("Billow Power");
|
|
public static GUIContent voronoiPower = EditorGUIUtility.TrTextContent("Voronoi Power");
|
|
public static GUIContent power = EditorGUIUtility.TrTextContent("Power");
|
|
public static GUIContent export = EditorGUIUtility.TrTextContent("Export", "Open a window providing options for exporting Noise to Textures");
|
|
public static GUIContent buttonLocked = EditorGUIUtility.TrTextContent("Locked", "The preview texture is currently locked for changes from mouse input. Click here to unlock it.");
|
|
public static GUIContent buttonUnlocked = EditorGUIUtility.TrTextContent("Unlocked", "The preview texture is currently active for changes from mouse input. Click here to lock it.");
|
|
public static GUIContent infoIcon = new GUIContent("", EditorGUIUtility.FindTexture("console.infoicon"),
|
|
"Scroll Mouse Wheel:\nZooms the preview in and out and changes the noise scale\n\n" +
|
|
"Left-mouse Drag:\nPans the noise field and changes the noise translation\n\n" +
|
|
"Color Key:\nCyan = negative noise values\nGrayscale = values between 0 and 1\nBlack = values are 0\nRed = Values greater than 1. Used for debugging texture normalization");
|
|
|
|
static Styles()
|
|
{
|
|
noisePreview = EditorGUIUtility.TrTextContent("Noise Field Preview:");
|
|
// ,
|
|
// "Scroll Mouse Wheel:\nZooms the preview in and out and changes the noise scale\n\n" +
|
|
// "Left-mouse Drag:\nPans the noise field and changes the noise translation\n\n" +
|
|
// "Color Key:\nCyan = negative noise values\nGrayscale = values between 0 and 1\nBlack = values are 0\nRed = Values greater than 1. Used for debugging texture normalization");
|
|
// noisePreview.image = infoIcon.image;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif |