using System; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEditor; using UnityEngine; using Object = UnityEngine.Object; namespace Pinwheel.Griffin.TextureTool { public class GTextureEditorWindow : GTwoPaneWindowWindow { private readonly int[] textureResolutionValues = new int[] { 32, 64, 128, 256, 512, 1024, 2048, 4096 }; private readonly string[] textureResolutionLabels = new string[] { "32", "64", "128", "256", "512", "1024", "2048*", "4096*" }; private const int PREVIEW_RGB = -1; private const int PREVIEW_R = 0; private const int PREVIEW_G = 1; private const int PREVIEW_B = 2; private const int PREVIEW_A = 3; private int previewMode = -1; private const int FILTER_POINT = 0; private const int FILTER_BILINEAR = 1; private int filterMode = 1; private int previewPadding = 10; private bool lockLivePreviewTerrain = false; private MaterialPropertyBlock livePreviewMaterialProperties; private RenderTexture previewRt; private RenderTexture PreviewRt { get { int resolution = GTextureToolParams.Instance.General.Resolution; RenderTextureFormat format = GTextureToolParams.Instance.General.UseHighPrecisionTexture ? RenderTextureFormat.ARGBFloat : RenderTextureFormat.ARGB32; if (previewRt == null) { previewRt = new RenderTexture(resolution, resolution, 32, format, RenderTextureReadWrite.Linear); } if (previewRt.width != resolution || previewRt.height != resolution || previewRt.format != format) { previewRt.Release(); GUtilities.DestroyObject(previewRt); previewRt = new RenderTexture(resolution, resolution, 32, format, RenderTextureReadWrite.Linear); } previewRt.wrapMode = TextureWrapMode.Clamp; previewRt.filterMode = (FilterMode)filterMode; return previewRt; } } private Material previewMat; private Material PreviewMat { get { if (previewMat == null) { previewMat = new Material(GRuntimeSettings.Instance.internalShaders.unlitChannelMaskShader); } return previewMat; } } public static void ShowWindow() { GTextureEditorWindow window = GetWindow(); window.titleContent = new GUIContent("Texture Creator"); window.minSize = new Vector2(400, 300); window.Show(); } public void OnEnable() { GCommon.RegisterBeginRender(OnBeginCameraRender); GCommon.RegisterBeginRenderSRP(OnBeginCameraRenderSRP); GTerrainData.GlobalDirty += OnTerrainDataDirty; livePreviewMaterialProperties = new MaterialPropertyBlock(); } public void OnDisable() { GCommon.UnregisterBeginRender(OnBeginCameraRender); GCommon.UnregisterBeginRenderSRP(OnBeginCameraRenderSRP); GTerrainData.GlobalDirty -= OnTerrainDataDirty; livePreviewMaterialProperties.Clear(); } private void OnFocus() { RenderPreviewTexture(); } private void OnDestroy() { if (previewRt != null) { previewRt.Release(); GUtilities.DestroyObject(previewRt); } if (previewMat != null) { GUtilities.DestroyObject(previewMat); } } protected override void OnToolbarGUI(Rect r) { base.OnToolbarGUI(r); List channelButtonLabels = new List() { "RGB", "R", "G", "B", "A" }; List channelValue = new List() { PREVIEW_RGB, PREVIEW_R, PREVIEW_G, PREVIEW_B, PREVIEW_A }; List channelButtonRects = EditorGUIUtility.GetFlowLayoutedRects(r, EditorStyles.toolbarButton, 0, 0, channelButtonLabels); for (int i = 0; i < channelButtonLabels.Count; ++i) { if (GUI.Button(channelButtonRects[i], channelButtonLabels[i], EditorStyles.toolbarButton)) { previewMode = channelValue[i]; } if (previewMode == channelValue[i]) { Color highlightColor = EditorGUIUtility.isProSkin ? new Color(1, 1, 1, 0.1f) : new Color(1, 1, 1, 0.3f); EditorGUI.DrawRect(channelButtonRects[i], highlightColor); } } List filterButtonLabels = new List() { "==============", "Point", "Bilinear" }; List filterValue = new List() { 0, FILTER_POINT, FILTER_BILINEAR }; List filterButtonRects = EditorGUIUtility.GetFlowLayoutedRects(r, EditorStyles.toolbarButton, 0, 0, filterButtonLabels); for (int i = 1; i < filterButtonLabels.Count; ++i) { if (GUI.Button(filterButtonRects[i], filterButtonLabels[i], EditorStyles.toolbarButton)) { filterMode = filterValue[i]; } if (filterMode == filterValue[i]) { Color highlightColor = EditorGUIUtility.isProSkin ? new Color(1, 1, 1, 0.1f) : new Color(1, 1, 1, 0.3f); EditorGUI.DrawRect(filterButtonRects[i], highlightColor); } } Rect saveButtonRect = new Rect( r.max.x - 100 - 2, r.min.y, 100, r.height); if (GUI.Button(saveButtonRect, "Save", EditorStyles.toolbarButton)) { SaveAsset(); } } protected override void OnLeftPaneGUI(Rect r) { base.OnLeftPaneGUI(r); Rect previewRect = new Rect(); int size = Mathf.FloorToInt(Mathf.Min(LeftPaneRect.width, LeftPaneRect.height) - 2 * previewPadding); previewRect.size = new Vector2(size, size); previewRect.center = LeftPaneRect.center; if (previewMode == PREVIEW_RGB) { EditorGUI.DrawPreviewTexture(previewRect, PreviewRt, null, ScaleMode.ScaleToFit); } else if (previewMode == PREVIEW_R) { PreviewMat.SetTexture("_MainTex", PreviewRt); PreviewMat.SetVector("_Mask", new Vector4(1, 0, 0, 0)); EditorGUI.DrawPreviewTexture(previewRect, PreviewRt, PreviewMat, ScaleMode.ScaleToFit); } else if (previewMode == PREVIEW_G) { PreviewMat.SetTexture("_MainTex", PreviewRt); PreviewMat.SetVector("_Mask", new Vector4(0, 1, 0, 0)); EditorGUI.DrawPreviewTexture(previewRect, PreviewRt, PreviewMat, ScaleMode.ScaleToFit); } else if (previewMode == PREVIEW_B) { PreviewMat.SetTexture("_MainTex", PreviewRt); PreviewMat.SetVector("_Mask", new Vector4(0, 0, 1, 0)); EditorGUI.DrawPreviewTexture(previewRect, PreviewRt, PreviewMat, ScaleMode.ScaleToFit); } else if (previewMode == PREVIEW_A) { EditorGUI.DrawTextureAlpha(previewRect, PreviewRt, ScaleMode.ScaleToFit); } } protected override void OnRightPaneScrollViewGUI() { EditorGUI.BeginChangeCheck(); base.OnRightPaneScrollViewGUI(); float labelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 120; DrawGeneralParamsGUI(); DrawSpecificParamsGUI(); DrawFilters(); DrawLivePreviewParamsGUI(); EditorGUIUtility.labelWidth = labelWidth; if (EditorGUI.EndChangeCheck()) { RenderPreviewTexture(); MarkParamAssetDirty(); } } private void MarkParamAssetDirty() { EditorUtility.SetDirty(GTextureToolParams.Instance); } private void DrawGeneralParamsGUI() { string id = "texture-editor-general"; string label = "General Parameters"; GEditorCommon.Foldout(label, true, id, () => { GGeneralParams param = GTextureToolParams.Instance.General; param.Mode = (GTextureGenerationMode)EditorGUILayout.EnumPopup("Mode", param.Mode); param.Resolution = EditorGUILayout.IntPopup("Resolution", param.Resolution, textureResolutionLabels, textureResolutionValues); param.Extension = (GImageFileExtension)EditorGUILayout.EnumPopup("Extension", param.Extension); param.UseHighPrecisionTexture = EditorGUILayout.Toggle("High Precision", param.UseHighPrecisionTexture); string dir = param.Directory; GEditorCommon.BrowseFolderMiniButton("Directory", ref dir); param.Directory = dir; GTextureToolParams.Instance.General = param; }); } private void DrawSpecificParamsGUI() { string id = "texture-editor-specific"; string label = "Specific Parameters"; GEditorCommon.Foldout(label, true, id, () => { GTextureGenerationMode mode = GTextureToolParams.Instance.General.Mode; string methodName = "Draw" + mode.ToString() + "Params"; MethodInfo guiMethod = typeof(GTextureEditorWindow).GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (guiMethod != null) { guiMethod.Invoke(this, null); } }); } private void DrawHeightMapParams() { GHeightMapGeneratorParams param = GTextureToolParams.Instance.HeightMap; param.Terrain = EditorGUILayout.ObjectField("Terrain", param.Terrain, typeof(GStylizedTerrain), true) as GStylizedTerrain; param.UseRealGeometry = EditorGUILayout.Toggle("Real Geometry", param.UseRealGeometry); lockLivePreviewTerrain = true; SetLivePreviewTerrain(param.Terrain); GTextureToolParams.Instance.HeightMap = param; } private void DrawHeightMapFromMeshParams() { GHeightMapFromMeshGeneratorParams param = GTextureToolParams.Instance.HeightMapFromMesh; bool isSrcMeshChanged = false; EditorGUI.BeginChangeCheck(); param.SrcMesh = EditorGUILayout.ObjectField("Mesh", param.SrcMesh, typeof(Mesh), false) as Mesh; if (EditorGUI.EndChangeCheck()) { isSrcMeshChanged = true; } GUI.enabled = param.SrcMesh != null; param.Offset = GEditorCommon.InlineVector3Field("Offset", param.Offset); param.Rotation = Quaternion.Euler(GEditorCommon.InlineVector3Field("Rotation", param.Rotation.eulerAngles)); param.Scale = GEditorCommon.InlineVector3Field("Scale", param.Scale); param.ProjectionDepth = EditorGUILayout.FloatField("Depth", param.ProjectionDepth); EditorGUILayout.LabelField("Camera", "Top Down", GEditorCommon.WordWrapItalicLabel); if (GUILayout.Button("Fit Camera") || isSrcMeshChanged) { Bounds bounds = param.SrcMesh.bounds; param.Rotation = Quaternion.identity; param.Scale = Vector3.one * GHeightMapFromMeshGenerator.DEFAULT_CAMERA_ORTHO_SIZE * 2f / (Mathf.Max(bounds.size.x, bounds.size.z) + 0.0001f); Matrix4x4 scaleMatrix = Matrix4x4.Scale(param.Scale); param.Offset = scaleMatrix.MultiplyPoint(new Vector3(0, -bounds.size.y * 0.5f, 0)); param.ProjectionDepth = scaleMatrix.MultiplyPoint(new Vector3(0, bounds.size.y, 0)).y; RenderPreviewTexture(); } GUI.enabled = true; lockLivePreviewTerrain = false; GTextureToolParams.Instance.HeightMapFromMesh = param; } private void DrawNormalMapParams() { GNormalMapGeneratorParams param = GTextureToolParams.Instance.NormalMap; param.Terrain = EditorGUILayout.ObjectField("Terrain", param.Terrain, typeof(GStylizedTerrain), true) as GStylizedTerrain; param.Mode = (GNormalMapMode)EditorGUILayout.EnumPopup("Mode", param.Mode); param.Space = (GNormalMapSpace)EditorGUILayout.EnumPopup("Space", param.Space); lockLivePreviewTerrain = true; SetLivePreviewTerrain(param.Terrain); GTextureToolParams.Instance.NormalMap = param; } private void DrawSteepnessMapParams() { GSteepnessMapGeneratorParams param = GTextureToolParams.Instance.Steepness; param.Terrain = EditorGUILayout.ObjectField("Terrain", param.Terrain, typeof(GStylizedTerrain), true) as GStylizedTerrain; param.Mode = (GNormalMapMode)EditorGUILayout.EnumPopup("Mode", param.Mode); lockLivePreviewTerrain = true; SetLivePreviewTerrain(param.Terrain); GTextureToolParams.Instance.Steepness = param; } private void DrawNoiseMapParams() { GNoiseMapGeneratorParams param = GTextureToolParams.Instance.Noise; param.Type = (GNoiseType)EditorGUILayout.EnumPopup("Type", param.Type); param.Origin = GEditorCommon.InlineVector2Field("Origin", param.Origin); param.Frequency = EditorGUILayout.FloatField("Frequency", param.Frequency); param.Lacunarity = EditorGUILayout.FloatField("Lacunarity", param.Lacunarity); param.Persistence = EditorGUILayout.FloatField("Persistence", param.Persistence); param.Octaves = EditorGUILayout.IntField("Octaves", param.Octaves); param.Seed = EditorGUILayout.FloatField("Seed", param.Seed); lockLivePreviewTerrain = false; GTextureToolParams.Instance.Noise = param; } private void DrawColorMapParams() { GColorMapGeneratorParams param = GTextureToolParams.Instance.ColorMap; param.Terrain = EditorGUILayout.ObjectField("Terrain", param.Terrain, typeof(GStylizedTerrain), true) as GStylizedTerrain; lockLivePreviewTerrain = true; SetLivePreviewTerrain(param.Terrain); GTextureToolParams.Instance.ColorMap = param; } private void DrawBlendMapParams() { GBlendMapGeneratorParams param = GTextureToolParams.Instance.Blend; List layers = param.Layers; for (int i = 0; i < layers.Count; ++i) { DrawBlendLayer(layers[i], i); GEditorCommon.Separator(); } if (GUILayout.Button("Add Layer")) { layers.Add(GBlendLayer.Create()); } GTextureToolParams.Instance.Blend = param; } private void DrawBlendLayer(GBlendLayer layer, int index) { string label = string.Format("{0} {1}", "Layer", index); string id = "texture-creator-blend-layer" + index; string prefKey = GEditorCommon.GetProjectRelatedEditorPrefsKey("foldout", id); bool expanded = EditorPrefs.GetBool(prefKey, true); int indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; Rect headerRect = EditorGUILayout.BeginHorizontal(); expanded = EditorGUILayout.Foldout(expanded, label); EditorPrefs.SetBool(prefKey, expanded); GUILayout.FlexibleSpace(); Rect deleteButtonRect = EditorGUILayout.GetControlRect(GUILayout.Width(15)); if (headerRect.Contains(Event.current.mousePosition)) { if (GUI.Button(deleteButtonRect, "X", EditorStyles.label)) { ConfirmAndRemoveBlendLayerAt(index); } } EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel = indent; if (expanded) { //EditorGUI.indentLevel += 1; layer.DataSource = (GBlendDataSource)EditorGUILayout.EnumPopup("Source", layer.DataSource); if (layer.DataSource == GBlendDataSource.Texture) { layer.Texture = GEditorCommon.InlineTexture2DField("Texture", layer.Texture, -1); } else if (layer.DataSource == GBlendDataSource.Number) { layer.Number = EditorGUILayout.FloatField("Number", layer.Number); } else if (layer.DataSource == GBlendDataSource.Vector) { layer.Vector = GEditorCommon.InlineVector4Field("Vector", layer.Vector); } if (index == 0) { layer.BlendOps = GBlendOperation.Add; } GUI.enabled = index != 0; layer.BlendOps = (GBlendOperation)EditorGUILayout.EnumPopup("Operation", layer.BlendOps); GUI.enabled = true; if (layer.BlendOps == GBlendOperation.Lerp) { layer.LerpFactor = EditorGUILayout.Slider("Factor", layer.LerpFactor, 0f, 1f); layer.LerpMask = GEditorCommon.InlineTexture2DField("Mask", layer.LerpMask, -1); } layer.Saturate = EditorGUILayout.Toggle("Saturate", layer.Saturate); //EditorGUI.indentLevel -= 1; } } private void ConfirmAndRemoveBlendLayerAt(int index) { if (EditorUtility.DisplayDialog( "Confirm", "Remove layer " + index.ToString() + "?", "OK", "Cancel")) { GTextureToolParams.Instance.Blend.Layers.RemoveAt(index); RenderPreviewTexture(); } } private void DrawFoliageDistributionMapParams() { GFoliageDistributionMapGeneratorParams param = GTextureToolParams.Instance.TreeDistribution; param.Terrain = EditorGUILayout.ObjectField("Terrain", param.Terrain, typeof(GStylizedTerrain), true) as GStylizedTerrain; param.BrushMask = GEditorCommon.InlineTexture2DField("Brush", param.BrushMask, -1); param.Opacity = EditorGUILayout.Slider("Opacity", param.Opacity, 0f, 1f); param.Size = EditorGUILayout.Slider("Size", param.Size, 0f, 1f); param.RotationMin = EditorGUILayout.FloatField("Rotation Min", param.RotationMin); param.RotationMax = EditorGUILayout.FloatField("Rotation Max", param.RotationMax); EditorGUILayout.LabelField("Trees"); if (param.Terrain == null || param.Terrain.TerrainData == null || param.Terrain.TerrainData.Foliage.Trees == null || param.Terrain.TerrainData.Foliage.Trees.Prototypes.Count == 0) { EditorGUILayout.LabelField("No tree found!", GEditorCommon.WordWrapItalicLabel); } else { List prototypes = param.Terrain.TerrainData.Foliage.Trees.Prototypes; GSelectionGridArgs args = new GSelectionGridArgs(); args.collection = prototypes; args.selectedIndices = param.TreePrototypeIndices; args.itemSize = GEditorCommon.selectionGridTileSizeSmall; args.itemPerRow = 4; args.drawPreviewFunction = GEditorCommon.DrawTreePreviewSingle; args.simpleMode = true; param.TreePrototypeIndices = GEditorCommon.MultiSelectionGrid(args); } EditorGUILayout.LabelField("Grasses"); if (param.Terrain == null || param.Terrain.TerrainData == null || param.Terrain.TerrainData.Foliage.Grasses == null || param.Terrain.TerrainData.Foliage.Grasses.Prototypes.Count == 0) { EditorGUILayout.LabelField("No grass found!", GEditorCommon.WordWrapItalicLabel); } else { List prototypes = param.Terrain.TerrainData.Foliage.Grasses.Prototypes; GSelectionGridArgs args = new GSelectionGridArgs(); args.collection = prototypes; args.selectedIndices = param.GrassPrototypeIndices; args.itemSize = GEditorCommon.selectionGridTileSizeSmall; args.itemPerRow = 4; args.drawPreviewFunction = GEditorCommon.DrawGrassPreview; args.simpleMode = true; param.GrassPrototypeIndices = GEditorCommon.MultiSelectionGrid(args); } lockLivePreviewTerrain = true; SetLivePreviewTerrain(param.Terrain); GTextureToolParams.Instance.TreeDistribution = param; } private void DrawFilters() { string id = "texture-editor-filters"; string label = "Filters"; GEditorCommon.Foldout(label, true, id, () => { List layers = GTextureToolParams.Instance.Filters; for (int i = 0; i < layers.Count; ++i) { DrawFilterLayer(layers[i], i); GEditorCommon.Separator(); } if (GUILayout.Button("Add Filter")) { GenericMenu menu = new GenericMenu(); Array types = Enum.GetValues(typeof(GTextureFilterType)); foreach (GTextureFilterType t in types) { menu.AddItem( new GUIContent(ObjectNames.NicifyVariableName(t.ToString())), false, () => { layers.Add(new GTextureFilterLayer(t)); RenderPreviewTexture(); }); } menu.ShowAsContext(); } }); } private void DrawFilterLayer(GTextureFilterLayer layer, int index) { string label = string.Format("{0} {1}", ObjectNames.NicifyVariableName(layer.Type.ToString()), layer.Enabled ? "" : "[-]"); string id = "texture-creator-filter" + index; string prefKey = GEditorCommon.GetProjectRelatedEditorPrefsKey("foldout", id); bool expanded = EditorPrefs.GetBool(prefKey, true); int indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; Rect headerRect = EditorGUILayout.BeginHorizontal(); expanded = EditorGUILayout.Foldout(expanded, label); EditorPrefs.SetBool(prefKey, expanded); GUILayout.FlexibleSpace(); Rect deleteButtonRect = EditorGUILayout.GetControlRect(GUILayout.Width(15)); if (headerRect.Contains(Event.current.mousePosition)) { if (GUI.Button(deleteButtonRect, "X", EditorStyles.label)) { ConfirmAndRemoveFilterAt(index); } } EditorGUILayout.EndHorizontal(); if (expanded) { EditorGUI.indentLevel += 1; layer.Enabled = EditorGUILayout.Toggle("Enable", layer.Enabled); GTextureFilterParams param = layer.Param; if (layer.Type == GTextureFilterType.Blur) { GBlurParams blur = param.Blur; blur.Radius = EditorGUILayout.DelayedIntField("Radius", blur.Radius); EditorGUILayout.LabelField("This filter is expensive!", GEditorCommon.WordWrapItalicLabel); param.Blur = blur; } else if (layer.Type == GTextureFilterType.Curve) { GCurveParams curve = param.Curve; curve.MasterCurve = EditorGUILayout.CurveField("Master", curve.MasterCurve, Color.white, GCommon.UnitRect); curve.RedCurve = EditorGUILayout.CurveField("Red", curve.RedCurve, Color.red, GCommon.UnitRect); curve.GreenCurve = EditorGUILayout.CurveField("Green", curve.GreenCurve, Color.green, GCommon.UnitRect); curve.BlueCurve = EditorGUILayout.CurveField("Blue", curve.BlueCurve, Color.blue, GCommon.UnitRect); curve.AlphaCurve = EditorGUILayout.CurveField("Alpha", curve.AlphaCurve, Color.gray, GCommon.UnitRect); param.Curve = curve; } else if (layer.Type == GTextureFilterType.Invert) { GInvertParams invert = param.Invert; invert.InvertRed = EditorGUILayout.Toggle("Red", invert.InvertRed); invert.InvertGreen = EditorGUILayout.Toggle("Green", invert.InvertGreen); invert.InvertBlue = EditorGUILayout.Toggle("Blue", invert.InvertBlue); invert.InvertAlpha = EditorGUILayout.Toggle("Alpha", invert.InvertAlpha); param.Invert = invert; } else if (layer.Type == GTextureFilterType.Step) { GStepParams step = param.Step; step.Count = EditorGUILayout.IntSlider("Count", step.Count, 1, 256); param.Step = step; } else if (layer.Type == GTextureFilterType.Warp) { GWarpParams warp = param.Warp; warp.MaskIsNormalMap = EditorGUILayout.Toggle("Is Normal Map", warp.MaskIsNormalMap); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Mask"); using (EditorGUI.IndentLevelScope level = new EditorGUI.IndentLevelScope(-1)) { warp.Mask = EditorGUILayout.ObjectField(warp.Mask, typeof(Texture2D), false) as Texture2D; } EditorGUILayout.EndHorizontal(); warp.Strength = EditorGUILayout.FloatField("Strength", warp.Strength); param.Warp = warp; } /* else if (layer.Type == GTextureFilterType.HydraulicErosion) { GHydraulicErosionParams erosion = param.HydraulicErosion; erosion.Iteration = EditorGUILayout.IntField("Iteration", erosion.Iteration); Vector3 dim = erosion.Dimension; dim = GEditorCommon.InlineVector3Field("Dimension", dim); dim.Set(Mathf.Max(1, dim.x), Mathf.Max(1, dim.y), Mathf.Max(1, dim.z)); erosion.Dimension = dim; erosion.Rain = EditorGUILayout.Slider("Rain", erosion.Rain, 0f, 1f); erosion.Transportation = EditorGUILayout.Slider("Transportation", erosion.Transportation, 0f, 1f); erosion.AngleMin = EditorGUILayout.Slider("Min Angle", erosion.AngleMin, 1f, 45f); erosion.Evaporation = EditorGUILayout.Slider("Evaporation", erosion.Evaporation, 0f, 1f); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Water Source"); using (EditorGUI.IndentLevelScope level = new EditorGUI.IndentLevelScope(-1)) { erosion.WaterSourceMap = EditorGUILayout.ObjectField(erosion.WaterSourceMap, typeof(Texture2D), false) as Texture2D; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Hardness"); using (EditorGUI.IndentLevelScope level = new EditorGUI.IndentLevelScope(-1)) { erosion.HardnessMap = EditorGUILayout.ObjectField(erosion.HardnessMap, typeof(Texture2D), false) as Texture2D; } EditorGUILayout.EndHorizontal(); param.HydraulicErosion = erosion; } */ layer.Param = param; EditorGUI.indentLevel -= 1; } EditorGUI.indentLevel = indent; } private void ConfirmAndRemoveFilterAt(int index) { GTextureFilterLayer layer = GTextureToolParams.Instance.Filters[index]; string layerName = ObjectNames.NicifyVariableName(layer.Type.ToString()); if (EditorUtility.DisplayDialog( "Confirm", "Remove filter " + layerName + "?", "OK", "Cancel")) { GTextureToolParams.Instance.Filters.RemoveAt(index); RenderPreviewTexture(); } } private void DrawLivePreviewParamsGUI() { string id = "texture-editor-live-preview"; string label = "Live Preview"; GEditorCommon.Foldout(label, true, id, () => { GLivePreviewParams param = GTextureToolParams.Instance.LivePreview; param.Enable = EditorGUILayout.Toggle("Enable", param.Enable); GUI.enabled = !lockLivePreviewTerrain; param.Terrain = EditorGUILayout.ObjectField("Terrain", param.Terrain, typeof(GStylizedTerrain), true) as GStylizedTerrain; GUI.enabled = param.Mode == GLivePreviewMode.Mask; param.Color = EditorGUILayout.ColorField("Color", param.Color); GUI.enabled = true; param.Mode = (GLivePreviewMode)EditorGUILayout.EnumPopup("Mode", param.Mode); GTextureToolParams.Instance.LivePreview = param; }); } private void SetLivePreviewTerrain(GStylizedTerrain terrain) { GLivePreviewParams param = GTextureToolParams.Instance.LivePreview; param.Terrain = terrain; GTextureToolParams.Instance.LivePreview = param; } private void RenderPreviewTexture() { PreviewRt.Release(); IGTextureGenerator generator = GetActiveGenerator(); if (generator != null) { generator.Generate(PreviewRt); } List layers = GTextureToolParams.Instance.Filters; for (int i = 0; i < layers.Count; ++i) { layers[i].Apply(PreviewRt); } SceneView.RepaintAll(); } private IGTextureGenerator GetActiveGenerator() { GTextureGenerationMode mode = GTextureToolParams.Instance.General.Mode; string className = "G" + mode.ToString() + "Generator"; Type type = GCommon.GetAllLoadedTypes().Find(t => t.Name.Equals(className)); if (type != null && type.GetInterface(typeof(IGTextureGenerator).Name) != null) { return Activator.CreateInstance(type) as IGTextureGenerator; } return null; } private void SaveAsset() { RecordAnalytics(); RenderPreviewTexture(); GGeneralParams generalParams = GTextureToolParams.Instance.General; GUtilities.EnsureDirectoryExists(generalParams.Directory); string ext = generalParams.Extension == GImageFileExtension.PNG ? "png" : generalParams.Extension == GImageFileExtension.JPG ? "jpg" : generalParams.Extension == GImageFileExtension.EXR ? "exr" : generalParams.Extension == GImageFileExtension.TGA ? "tga" : "file"; string fileName = string.Format("{0}_{1}.{2}", GCommon.GetTimeTick(), generalParams.Mode.ToString(), ext); string filePath = Path.Combine(generalParams.Directory, fileName); TextureFormat format = generalParams.UseHighPrecisionTexture ? TextureFormat.RGBAFloat : TextureFormat.RGBA32; Texture2D tex = new Texture2D(generalParams.Resolution, generalParams.Resolution, format, false); tex.wrapMode = TextureWrapMode.Clamp; GCommon.CopyFromRT(tex, PreviewRt); byte[] data = generalParams.Extension == GImageFileExtension.PNG ? tex.EncodeToPNG() : generalParams.Extension == GImageFileExtension.JPG ? tex.EncodeToPNG() : generalParams.Extension == GImageFileExtension.EXR ? tex.EncodeToPNG() : generalParams.Extension == GImageFileExtension.TGA ? tex.EncodeToPNG() : new byte[0]; File.WriteAllBytes(filePath, data); GUtilities.DestroyObject(tex); AssetDatabase.Refresh(); Object o = AssetDatabase.LoadAssetAtPath(filePath); if (o != null) { EditorGUIUtility.PingObject(o); Selection.activeObject = o; } } private void OnBeginCameraRender(Camera cam) { GLivePreviewParams livePreviewParam = GTextureToolParams.Instance.LivePreview; if (!livePreviewParam.Enable || livePreviewParam.Terrain == null) return; GGeneralParams generalParam = GTextureToolParams.Instance.General; Material mat = GInternalMaterials.UnlitTextureMaterial; livePreviewMaterialProperties.Clear(); if (livePreviewParam.Mode == GLivePreviewMode.Mask) { mat = GInternalMaterials.MaskVisualizerMaterial; livePreviewMaterialProperties.SetTexture("_MainTex", PreviewRt); livePreviewMaterialProperties.SetColor("_Color", livePreviewParam.Color); } else if (livePreviewParam.Mode == GLivePreviewMode.ColorMap) { mat = GInternalMaterials.UnlitTextureMaterial; livePreviewMaterialProperties.SetTexture("_MainTex", PreviewRt); } else if (livePreviewParam.Mode == GLivePreviewMode.Geometry) { mat = GInternalMaterials.GeometryLivePreviewMaterial; GStylizedTerrain t = livePreviewParam.Terrain; Vector3 terrainSize = new Vector3( t.TerrainData.Geometry.Width, t.TerrainData.Geometry.Height, t.TerrainData.Geometry.Length); livePreviewMaterialProperties.SetTexture("_OldHeightMap", t.TerrainData.Geometry.HeightMap); livePreviewMaterialProperties.SetTexture("_NewHeightMap", PreviewRt); livePreviewMaterialProperties.SetTexture("_MainTex", PreviewRt); livePreviewMaterialProperties.SetFloat("_Height", t.TerrainData.Geometry.Height); livePreviewMaterialProperties.SetVector("_BoundMin", t.transform.position); livePreviewMaterialProperties.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize)); } GTerrainChunk[] chunks = livePreviewParam.Terrain.GetChunks(); for (int i = 0; i < chunks.Length; ++i) { Mesh m = chunks[i].MeshFilterComponent.sharedMesh; if (m == null) continue; Graphics.DrawMesh( m, chunks[i].transform.localToWorldMatrix, mat, chunks[i].gameObject.layer, cam, 0, livePreviewMaterialProperties, false, false); } } private void OnBeginCameraRenderSRP(UnityEngine.Rendering.ScriptableRenderContext context, Camera cam) { OnBeginCameraRender(cam); } private void OnTerrainDataDirty(GTerrainData data, GTerrainData.DirtyFlags flag) { GStylizedTerrain t = GTextureToolParams.Instance.LivePreview.Terrain; if (t == null || t.TerrainData != data) return; RenderPreviewTexture(); } private void RecordAnalytics() { GTextureGenerationMode mode = GTextureToolParams.Instance.General.Mode; string url = mode == GTextureGenerationMode.HeightMap ? GAnalytics.TEXTURE_CREATOR_HEIGHT_MAP : mode == GTextureGenerationMode.HeightMapFromMesh ? GAnalytics.TEXTURE_CREATOR_HEIGHT_MAP_FROM_MESH : mode == GTextureGenerationMode.NormalMap ? GAnalytics.TEXTURE_CREATOR_NORMAL_MAP : mode == GTextureGenerationMode.SteepnessMap ? GAnalytics.TEXTURE_CREATOR_STEEPNESS_MAP : mode == GTextureGenerationMode.ColorMap ? GAnalytics.TEXTURE_CREATOR_COLOR_MAP : mode == GTextureGenerationMode.NoiseMap ? GAnalytics.TEXTURE_CREATOR_NOISE_MAP : mode == GTextureGenerationMode.BlendMap ? GAnalytics.TEXTURE_CREATOR_BLEND_MAP : mode == GTextureGenerationMode.FoliageDistributionMap ? GAnalytics.TEXTURE_CREATOR_FOLIAGE_DISTRIBUTION_MAP : string.Empty; GAnalytics.Record(url); } } }