using Pinwheel.Griffin.BackupTool; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace Pinwheel.Griffin.SplineTool { [CustomEditor(typeof(GFoliageSpawner))] public class GFoliageSpawnerInspector : Editor { private GFoliageSpawner instance; private Dictionary previewTextures; private MaterialPropertyBlock previewPropertyBlock; private const string HISTORY_PREFIX = "Spawn Foliage Along Path"; private void OnEnable() { Undo.undoRedoPerformed += OnUndoRedo; instance = target as GFoliageSpawner; instance.Internal_UpdateFalloffTexture(); previewPropertyBlock = new MaterialPropertyBlock(); GCommon.RegisterBeginRender(OnCameraRender); GCommon.RegisterBeginRenderSRP(OnCameraRenderSRP); } private void OnDisable() { Undo.undoRedoPerformed -= OnUndoRedo; GCommon.UnregisterBeginRender(OnCameraRender); GCommon.UnregisterBeginRenderSRP(OnCameraRenderSRP); if (previewTextures != null) { foreach (GStylizedTerrain t in previewTextures.Keys) { RenderTexture rt = previewTextures[t]; if (rt == null) continue; rt.Release(); Object.DestroyImmediate(rt); } } } private void OnUndoRedo() { if (Selection.activeGameObject != instance.gameObject) return; if (string.IsNullOrEmpty(GUndoCompatibleBuffer.Instance.CurrentBackupName)) return; GBackup.Restore(GUndoCompatibleBuffer.Instance.CurrentBackupName); } public override void OnInspectorGUI() { instance.SplineCreator = EditorGUILayout.ObjectField("Spline Creator", instance.SplineCreator, typeof(GSplineCreator), true) as GSplineCreator; if (instance.SplineCreator == null) return; bool wideMode = EditorGUIUtility.wideMode; EditorGUIUtility.wideMode = true; EditorGUI.BeginChangeCheck(); instance.Falloff = EditorGUILayout.CurveField("Falloff", instance.Falloff, Color.red, new Rect(0, 0, 1, 1)); if (EditorGUI.EndChangeCheck()) { instance.Internal_UpdateFalloffTexture(); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Falloff Noise"); instance.FalloffNoise = EditorGUILayout.ObjectField(instance.FalloffNoise, typeof(Texture2D), false) as Texture2D; EditorGUILayout.EndHorizontal(); if (instance.FalloffNoise != null) instance.FalloffNoiseSize = EditorGUILayout.Vector2Field("Falloff Noise Size", instance.FalloffNoiseSize); instance.MaskResolution = EditorGUILayout.DelayedIntField("Mask Resolution", instance.MaskResolution); instance.SpawnTrees = EditorGUILayout.Toggle("Spawn Trees", instance.SpawnTrees); if (instance.SpawnTrees) { EditorGUI.indentLevel += 1; instance.TreePrototypeIndices = GEditorCommon.TreeSetMultiSelectionGrid(instance.SplineCreator.GroupId, instance.TreePrototypeIndices); instance.TreeDensity = EditorGUILayout.IntField("Density", instance.TreeDensity); EditorGUI.indentLevel -= 1; } instance.SpawnGrasses = EditorGUILayout.Toggle("Spawn Grasses", instance.SpawnGrasses); if (instance.SpawnGrasses) { EditorGUI.indentLevel += 1; instance.GrassPrototypeIndices = GEditorCommon.GrassSetMultiSelectionGrid(instance.SplineCreator.GroupId, instance.GrassPrototypeIndices); instance.GrassDensity = EditorGUILayout.IntField("Density", instance.GrassDensity); EditorGUI.indentLevel -= 1; } instance.MinRotation = EditorGUILayout.FloatField("Min Rotation", instance.MinRotation); instance.MaxRotation = EditorGUILayout.FloatField("Max Rotation", instance.MaxRotation); instance.MinScale = GEditorCommon.InlineVector3Field("Min Scale", instance.MinScale); instance.MaxScale = GEditorCommon.InlineVector3Field("Max Scale", instance.MaxScale); instance.Editor_ShowLivePreview = EditorGUILayout.Toggle("Live Preview", instance.Editor_ShowLivePreview); EditorGUIUtility.wideMode = wideMode; EditorGUILayout.Space(); if (GUILayout.Button("Apply")) { GAnalytics.Record(GAnalytics.SPLINE_FOLIAGE_SPAWNER); CreateInitialBackup(); Apply(); CreateBackupAfterApply(); } } private void CreateInitialBackup() { //GBackup.TryCreateInitialBackup(HISTORY_PREFIX, instance.SplineCreator.GroupId, GCommon.FoliageInstancesResourceFlags); List terrains = GSplineToolUtilities.OverlapTest(instance.SplineCreator.GroupId, instance.SplineCreator); GBackupInternal.TryCreateAndMergeInitialBackup(HISTORY_PREFIX, terrains, GCommon.FoliageInstancesResourceFlags, true); } private void Apply() { EditorUtility.DisplayProgressBar("Applying", "Spawning foliage...", 1f); try { instance.Apply(); } catch (System.Exception e) { Debug.LogError(e.ToString()); } EditorUtility.ClearProgressBar(); } private void CreateBackupAfterApply() { //GBackup.TryCreateBackup(HISTORY_PREFIX, instance.SplineCreator.GroupId, GCommon.FoliageInstancesResourceFlags); List terrains = GSplineToolUtilities.OverlapTest(instance.SplineCreator.GroupId, instance.SplineCreator); GBackupInternal.TryCreateAndMergeBackup(HISTORY_PREFIX, terrains, GCommon.FoliageInstancesResourceFlags, true); } private void OnCameraRender(Camera cam) { if (instance.Editor_ShowLivePreview) DrawLivePreview(cam); } private void OnCameraRenderSRP(UnityEngine.Rendering.ScriptableRenderContext context, Camera cam) { OnCameraRender(cam); } private void DrawLivePreview(Camera cam) { IEnumerator terrains = GStylizedTerrain.ActiveTerrains.GetEnumerator(); while (terrains.MoveNext()) { GStylizedTerrain t = terrains.Current; if (t.TerrainData == null) continue; if (instance.SplineCreator.GroupId >= 0 && instance.SplineCreator.GroupId != t.GroupId) continue; DrawLivePreview(t, cam); } } private void DrawLivePreview(GStylizedTerrain t, Camera cam) { if (t.transform.rotation != Quaternion.identity || t.transform.lossyScale != Vector3.one) return; List dirtyRects = new List(instance.SplineCreator.SweepDirtyRect(t)); Rect r = new Rect(0, 0, 0, 0); for (int i = 0; i < dirtyRects.Count; ++i) { r.xMin = Mathf.Min(r.xMin, dirtyRects[i].xMin); r.xMax = Mathf.Max(r.xMax, dirtyRects[i].xMax); r.yMin = Mathf.Min(r.yMin, dirtyRects[i].yMin); r.yMax = Mathf.Max(r.yMax, dirtyRects[i].yMax); } RenderTexture rt = GetPreviewTexture(t); instance.Internal_Apply(t, rt, instance.SplineCreator.Editor_Vertices); GLivePreviewDrawer.DrawMasksLivePreview( t, cam, new Texture[] { rt }, new Color[] { GEditorSettings.Instance.splineTools.positiveHighlightColor }, r); } private RenderTexture GetPreviewTexture(GStylizedTerrain t) { if (previewTextures == null) { previewTextures = new Dictionary(); } int resolution = instance.MaskResolution; if (!previewTextures.ContainsKey(t) || previewTextures[t] == null) { RenderTexture rt = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); previewTextures[t] = rt; } else if (previewTextures[t].width != resolution || previewTextures[t].height != resolution) { previewTextures[t].Release(); Object.DestroyImmediate(previewTextures[t]); RenderTexture rt = new RenderTexture(resolution, resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); previewTextures[t] = rt; } previewTextures[t].wrapMode = TextureWrapMode.Clamp; return previewTextures[t]; } } }