Files
3d-qiaozha/Assets/NatureManufacture Assets/Spline System/Scripts/LakePolygon/Editor/LakePolygonEditor.cs
2026-03-10 10:07:11 +08:00

1892 lines
75 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.IO;
using UnityEngine.Rendering;
#if VEGETATION_STUDIO_PRO
using AwesomeTechnologies;
using AwesomeTechnologies.VegetationSystem;
using AwesomeTechnologies.VegetationSystem.Biomes;
#endif
#if VEGETATION_STUDIO
using AwesomeTechnologies;
using AwesomeTechnologies.VegetationStudio;
#endif
[CustomEditor(typeof(LakePolygon))]
public class LakePolygonEditor : Editor
{
LakePolygon[] lakes;
LakePolygon lakePolygon;
int selectedPosition = -1;
Texture2D logo;
bool showCarveTerrain = false;
public string[] toolbarStrings = new string[]
{
"Basic",
"Points",
"Vertex Color",
"Flow Map",
"Simulate\n[ALPHA] ",
"Terrain",
"File Points",
"Tips",
"Manual",
"Video Tutorials"
#if VEGETATION_STUDIO
,
"Vegetation Studio"
#endif
#if VEGETATION_STUDIO_PRO
,
"Vegetation Studio Pro"
#endif
};
Mesh meshTerrain;
[MenuItem("GameObject/3D Object/Create Lake Polygon")]
static public void CreatelakePolygon()
{
Selection.activeGameObject = LakePolygon.CreatePolygon(AssetDatabase.GetBuiltinExtraResource<Material>("Default-Diffuse.mat")).gameObject;
}
void OnEnable()
{
lakes = FindObjectsOfType<LakePolygon>();
SceneView.duringSceneGui -= this.OnSceneGUIInvoke;
SceneView.duringSceneGui += this.OnSceneGUIInvoke;
}
private void OnDisable()
{
if (lakePolygon == null)
lakePolygon = (LakePolygon) target;
if (lakePolygon.meshGOs != null && lakePolygon.meshGOs.Count > 0)
{
foreach (var item in lakePolygon.meshGOs)
{
DestroyImmediate(item);
}
lakePolygon.meshGOs.Clear();
}
if (lakePolygon.lakePolygonCarveData != null)
lakePolygon.lakePolygonCarveData = null;
if (lakePolygon.lakePolygonPaintData != null)
lakePolygon.lakePolygonPaintData = null;
if (lakePolygon.lakePolygonClearData != null)
lakePolygon.lakePolygonClearData = null;
SceneView.duringSceneGui -= this.OnSceneGUIInvoke;
}
private void OnDestroy()
{
if (lakePolygon == null)
lakePolygon = (LakePolygon) target;
if (lakePolygon.meshGOs != null && lakePolygon.meshGOs.Count > 0)
{
foreach (var item in lakePolygon.meshGOs)
{
DestroyImmediate(item);
}
lakePolygon.meshGOs.Clear();
}
if (lakePolygon.lakePolygonCarveData != null)
lakePolygon.lakePolygonCarveData = null;
if (lakePolygon.lakePolygonPaintData != null)
lakePolygon.lakePolygonPaintData = null;
if (lakePolygon.lakePolygonClearData != null)
lakePolygon.lakePolygonClearData = null;
}
public override void OnInspectorGUI()
{
if (lakePolygon == null)
lakePolygon = (LakePolygon) target;
EditorGUILayout.Space();
logo = (Texture2D) Resources.Load("logoRAM");
GUIContent btnTxt = new GUIContent(logo);
var rt = GUILayoutUtility.GetRect(btnTxt, GUI.skin.label, GUILayout.ExpandWidth(false));
rt.center = new Vector2(EditorGUIUtility.currentViewWidth / 2, rt.center.y);
GUI.Button(rt, btnTxt, GUI.skin.label);
int toolbarNew = GUILayout.SelectionGrid(lakePolygon.toolbarInt, toolbarStrings, 3, GUILayout.Height(125));
lakePolygon.drawOnMesh = false;
lakePolygon.drawOnMeshFlowMap = false;
if (lakePolygon.transform.eulerAngles.magnitude != 0 || lakePolygon.transform.localScale.x != 1 || lakePolygon.transform.localScale.y != 1 || lakePolygon.transform.localScale.z != 1)
EditorGUILayout.HelpBox("Lake should have scale (1,1,1) and rotation (0,0,0) during edit!", MessageType.Error);
if (toolbarNew == 0)
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Add Point - CTRL + Left Mouse Button Click \n" +
"Add point between existing points - SHIFT + Left Button Click \n" +
"Remove point - CTRL + SHIFT + Left Button Click", MessageType.Info);
EditorGUILayout.Space();
lakePolygon.currentProfile = (LakePolygonProfile) EditorGUILayout.ObjectField("Lake profile", lakePolygon.currentProfile, typeof(LakePolygonProfile), false);
if (GUILayout.Button("Create profile from settings"))
{
LakePolygonProfile asset = ScriptableObject.CreateInstance<LakePolygonProfile>();
MeshRenderer ren = lakePolygon.GetComponent<MeshRenderer>();
asset.terrainCarve = new AnimationCurve(lakePolygon.terrainCarve.keys);
asset.terrainPaintCarve = new AnimationCurve(lakePolygon.terrainPaintCarve.keys);
asset.lakeMaterial = ren.sharedMaterial;
asset.distSmooth = lakePolygon.distSmooth;
asset.uvScale = lakePolygon.uvScale;
asset.terrainSmoothMultiplier = lakePolygon.terrainSmoothMultiplier;
asset.currentSplatMap = lakePolygon.currentSplatMap;
asset.maximumTriangleSize = lakePolygon.maximumTriangleSize;
asset.traingleDensity = lakePolygon.traingleDensity;
asset.receiveShadows = lakePolygon.receiveShadows;
asset.shadowCastingMode = lakePolygon.shadowCastingMode;
asset.automaticFlowMapScale = lakePolygon.automaticFlowMapScale;
asset.noiseflowMap = lakePolygon.noiseflowMap;
asset.noiseMultiplierflowMap = lakePolygon.noiseMultiplierflowMap;
asset.noiseSizeXflowMap = lakePolygon.noiseSizeXflowMap;
asset.noiseSizeZflowMap = lakePolygon.noiseSizeZflowMap;
asset.noiseCarve = lakePolygon.noiseCarve;
asset.noiseMultiplierInside = lakePolygon.noiseMultiplierInside;
asset.noiseMultiplierOutside = lakePolygon.noiseMultiplierOutside;
asset.noiseSizeX = lakePolygon.noiseSizeX;
asset.noiseSizeZ = lakePolygon.noiseSizeZ;
asset.noisePaint = lakePolygon.noisePaint;
asset.noiseMultiplierInsidePaint = lakePolygon.noiseMultiplierInsidePaint;
asset.noiseMultiplierOutsidePaint = lakePolygon.noiseMultiplierOutsidePaint;
asset.noiseSizeXPaint = lakePolygon.noiseSizeXPaint;
asset.noiseSizeZPaint = lakePolygon.noiseSizeZPaint;
asset.mixTwoSplatMaps = lakePolygon.mixTwoSplatMaps;
asset.secondSplatMap = lakePolygon.secondSplatMap;
asset.addCliffSplatMap = lakePolygon.addCliffSplatMap;
asset.cliffSplatMap = lakePolygon.cliffSplatMap;
asset.cliffAngle = lakePolygon.cliffAngle;
asset.cliffBlend = lakePolygon.cliffBlend;
asset.cliffSplatMapOutside = lakePolygon.cliffSplatMapOutside;
asset.cliffAngleOutside = lakePolygon.cliffAngleOutside;
asset.cliffBlendOutside = lakePolygon.cliffBlendOutside;
asset.distanceClearFoliage = lakePolygon.distanceClearFoliage;
asset.distanceClearFoliageTrees = lakePolygon.distanceClearFoliageTrees;
string path = EditorUtility.SaveFilePanelInProject("Save new spline profile", lakePolygon.gameObject.name + ".asset", "asset",
"Please enter a file name to save the spline profile to");
if (!string.IsNullOrEmpty(path))
{
AssetDatabase.CreateAsset(asset, path);
AssetDatabase.SaveAssets();
lakePolygon.currentProfile = asset;
}
}
if (lakePolygon.currentProfile != null && GUILayout.Button("Save profile from settings"))
{
MeshRenderer ren = lakePolygon.GetComponent<MeshRenderer>();
lakePolygon.currentProfile.terrainCarve = new AnimationCurve(lakePolygon.terrainCarve.keys);
lakePolygon.currentProfile.terrainPaintCarve = new AnimationCurve(lakePolygon.terrainPaintCarve.keys);
lakePolygon.currentProfile.lakeMaterial = ren.sharedMaterial;
lakePolygon.currentProfile.distSmooth = lakePolygon.distSmooth;
lakePolygon.currentProfile.uvScale = lakePolygon.uvScale;
lakePolygon.currentProfile.terrainSmoothMultiplier = lakePolygon.terrainSmoothMultiplier;
lakePolygon.currentProfile.currentSplatMap = lakePolygon.currentSplatMap;
lakePolygon.currentProfile.maximumTriangleSize = lakePolygon.maximumTriangleSize;
lakePolygon.currentProfile.traingleDensity = lakePolygon.traingleDensity;
lakePolygon.currentProfile.receiveShadows = lakePolygon.receiveShadows;
lakePolygon.currentProfile.shadowCastingMode = lakePolygon.shadowCastingMode;
lakePolygon.currentProfile.automaticFlowMapScale = lakePolygon.automaticFlowMapScale;
lakePolygon.currentProfile.noiseflowMap = lakePolygon.noiseflowMap;
lakePolygon.currentProfile.noiseMultiplierflowMap = lakePolygon.noiseMultiplierflowMap;
lakePolygon.currentProfile.noiseSizeXflowMap = lakePolygon.noiseSizeXflowMap;
lakePolygon.currentProfile.noiseSizeZflowMap = lakePolygon.noiseSizeZflowMap;
lakePolygon.currentProfile.noiseCarve = lakePolygon.noiseCarve;
lakePolygon.currentProfile.noiseMultiplierInside = lakePolygon.noiseMultiplierInside;
lakePolygon.currentProfile.noiseMultiplierOutside = lakePolygon.noiseMultiplierOutside;
lakePolygon.currentProfile.noiseSizeX = lakePolygon.noiseSizeX;
lakePolygon.currentProfile.noiseSizeZ = lakePolygon.noiseSizeZ;
lakePolygon.currentProfile.noisePaint = lakePolygon.noisePaint;
lakePolygon.currentProfile.noiseMultiplierInsidePaint = lakePolygon.noiseMultiplierInsidePaint;
lakePolygon.currentProfile.noiseMultiplierOutsidePaint = lakePolygon.noiseMultiplierOutsidePaint;
lakePolygon.currentProfile.noiseSizeXPaint = lakePolygon.noiseSizeXPaint;
lakePolygon.currentProfile.noiseSizeZPaint = lakePolygon.noiseSizeZPaint;
lakePolygon.currentProfile.mixTwoSplatMaps = lakePolygon.mixTwoSplatMaps;
lakePolygon.currentProfile.secondSplatMap = lakePolygon.secondSplatMap;
lakePolygon.currentProfile.addCliffSplatMap = lakePolygon.addCliffSplatMap;
lakePolygon.currentProfile.cliffSplatMap = lakePolygon.cliffSplatMap;
lakePolygon.currentProfile.cliffAngle = lakePolygon.cliffAngle;
lakePolygon.currentProfile.cliffBlend = lakePolygon.cliffBlend;
lakePolygon.currentProfile.cliffSplatMapOutside = lakePolygon.cliffSplatMapOutside;
lakePolygon.currentProfile.cliffAngleOutside = lakePolygon.cliffAngleOutside;
lakePolygon.currentProfile.cliffBlendOutside = lakePolygon.cliffBlendOutside;
lakePolygon.currentProfile.distanceClearFoliage = lakePolygon.distanceClearFoliage;
lakePolygon.currentProfile.distanceClearFoliageTrees = lakePolygon.distanceClearFoliageTrees;
AssetDatabase.SaveAssets();
}
if (lakePolygon.currentProfile != null && lakePolygon.currentProfile != lakePolygon.oldProfile)
{
ResetToProfile();
lakePolygon.GeneratePolygon();
EditorUtility.SetDirty(lakePolygon);
}
if (CheckProfileChange())
EditorGUILayout.HelpBox("Profile data changed.", MessageType.Info);
if (lakePolygon.currentProfile != null && GUILayout.Button("Reset to profile"))
{
ResetToProfile();
}
EditorGUILayout.Space();
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.lockHeight = EditorGUILayout.Toggle("Lock height", lakePolygon.lockHeight);
EditorGUILayout.BeginHorizontal();
lakePolygon.height = EditorGUILayout.FloatField(lakePolygon.height);
if (GUILayout.Button("Set heights"))
{
for (int i = 0; i < lakePolygon.points.Count; i++)
{
Vector3 point = lakePolygon.points[i];
point.y = lakePolygon.height - lakePolygon.transform.position.y;
lakePolygon.points[i] = point;
}
lakePolygon.GeneratePolygon();
}
EditorGUILayout.EndHorizontal();
lakePolygon.yOffset = EditorGUILayout.FloatField("Y offset mesh", lakePolygon.yOffset);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
GUILayout.Label("Mesh settings:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUI.indentLevel++;
string meshResolution = "Triangles density" + "(" + lakePolygon.trianglesGenerated + " tris)";
EditorGUILayout.LabelField(meshResolution);
if (lakePolygon.vertsGenerated > 65000)
{
EditorGUILayout.HelpBox("Too many vertices for 16 bit mesh index buffer. Mesh switched to 32 bit index buffer.", MessageType.Warning);
}
float maximumTriangleSize = EditorGUILayout.DelayedFloatField("Maximum triangle size", lakePolygon.maximumTriangleSize);
if (maximumTriangleSize != lakePolygon.maximumTriangleSize)
{
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.maximumTriangleSize = maximumTriangleSize;
}
if (lakePolygon.maximumTriangleSize == 0)
lakePolygon.maximumTriangleSize = 50;
lakePolygon.traingleDensity = 1 / (float) EditorGUILayout.IntSlider("Spline density", (int) (1 / (float) lakePolygon.traingleDensity), 1, 100);
lakePolygon.uvScale = EditorGUILayout.FloatField("UV scale", lakePolygon.uvScale);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
if (GUILayout.Button("Snap/Unsnap mesh to terrain"))
{
lakePolygon.snapToTerrain = !lakePolygon.snapToTerrain;
}
EditorGUI.indentLevel++;
///spline.snapMask = EditorGUILayout.MaskField ("Layers", spline.snapMask, InternalEditorUtility.layers);
lakePolygon.snapMask = RamSplineEditor.LayerMaskField("Layers", lakePolygon.snapMask, true);
lakePolygon.normalFromRaycast = EditorGUILayout.Toggle("Take Normal from terrain", lakePolygon.normalFromRaycast);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
GUILayout.Label("Lightning settings:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
lakePolygon.receiveShadows = EditorGUILayout.Toggle("Receive Shadows", lakePolygon.receiveShadows);
lakePolygon.shadowCastingMode = (ShadowCastingMode) EditorGUILayout.EnumPopup("Shadow Casting Mode", lakePolygon.shadowCastingMode);
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.GeneratePolygon();
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
if (GUILayout.Button("Generate polygon"))
{
lakePolygon.GeneratePolygon();
}
EditorGUILayout.Space();
if (GUILayout.Button("Export as mesh"))
{
string path = EditorUtility.SaveFilePanelInProject("Save lake mesh", "", "asset", "Save lake mesh");
if (path.Length != 0 && lakePolygon.meshfilter.sharedMesh != null)
{
AssetDatabase.CreateAsset(lakePolygon.meshfilter.sharedMesh, path);
AssetDatabase.Refresh();
lakePolygon.GeneratePolygon();
}
}
}
if (toolbarNew == 1)
{
EditorGUILayout.Space();
PointsUI();
}
if (lakePolygon.toolbarInt == 2)
{
DrawVertexColorsUI();
}
if (lakePolygon.toolbarInt == 3)
{
DrawFlowColorsUI();
}
if (lakePolygon.toolbarInt == 4)
{
EditorGUILayout.HelpBox("\nSet 1 point and R.A.M will generate lake.\n", MessageType.Info);
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
Undo.RecordObject(lakePolygon, "Lake curve changed");
lakePolygon.angleSimulation = EditorGUILayout.IntSlider("Angle", lakePolygon.angleSimulation, 1, 180);
lakePolygon.closeDistanceSimulation = EditorGUILayout.FloatField("Point distance", lakePolygon.closeDistanceSimulation);
lakePolygon.checkDistanceSimulation = EditorGUILayout.FloatField("Check distance", lakePolygon.checkDistanceSimulation);
lakePolygon.removeFirstPointSimulation = EditorGUILayout.Toggle("Remove first point", lakePolygon.removeFirstPointSimulation);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake curve changed");
}
if (GUILayout.Button("Simulate"))
{
lakePolygon.Simulation();
}
if (GUILayout.Button("Remove points except first"))
{
lakePolygon.RemovePoints(0);
lakePolygon.meshfilter.sharedMesh = null;
}
if (GUILayout.Button("Remove all points"))
{
lakePolygon.RemovePoints();
lakePolygon.meshfilter.sharedMesh = null;
}
}
if (toolbarNew == 5)
{
EditorGUILayout.Space();
Terrain terrain = Terrain.activeTerrain;
if (terrain != null && terrain.terrainData != null)
{
GUILayout.Label("Terrain carve:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
Undo.RecordObject(lakePolygon, "Lake curve changed");
lakePolygon.terrainCarve = EditorGUILayout.CurveField("Terrain carve", lakePolygon.terrainCarve);
lakePolygon.terrainSmoothMultiplier = EditorGUILayout.FloatField("Smooth", lakePolygon.terrainSmoothMultiplier);
lakePolygon.distSmooth = EditorGUILayout.FloatField("Smooth distance", lakePolygon.distSmooth);
lakePolygon.noiseCarve = EditorGUILayout.Toggle("Add noise", lakePolygon.noiseCarve);
if (lakePolygon.noiseCarve)
{
EditorGUI.indentLevel++;
lakePolygon.noiseMultiplierInside = EditorGUILayout.FloatField("Noise multiplier inside", lakePolygon.noiseMultiplierInside);
lakePolygon.noiseMultiplierOutside = EditorGUILayout.FloatField("Noise multiplier outside", lakePolygon.noiseMultiplierOutside);
lakePolygon.noiseSizeX = EditorGUILayout.FloatField("Noise scale X", lakePolygon.noiseSizeX);
lakePolygon.noiseSizeZ = EditorGUILayout.FloatField("Noise scale Z", lakePolygon.noiseSizeZ);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
if (EditorGUI.EndChangeCheck())
{
if (showCarveTerrain)
lakePolygon.TerrainCarve(true);
Undo.RecordObject(lakePolygon, "Lake curve changed");
}
EditorGUI.indentLevel--;
if (!showCarveTerrain)
{
if (GUILayout.Button("Show Terrain Carve"))
{
showCarveTerrain = true;
lakePolygon.TerrainCarve(true);
}
}
else
{
if (GUILayout.Button("Hide Terrain Carve"))
{
showCarveTerrain = false;
if (lakePolygon.meshGOs != null && lakePolygon.meshGOs.Count > 0)
{
foreach (var item in lakePolygon.meshGOs)
{
DestroyImmediate(item);
}
lakePolygon.meshGOs.Clear();
}
}
}
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
lakePolygon.overrideLakeRender = EditorGUILayout.Toggle("Debug Override lake render", lakePolygon.overrideLakeRender);
EditorGUI.indentLevel--;
if (GUILayout.Button("Carve Terrain"))
{
showCarveTerrain = false;
lakePolygon.TerrainCarve();
}
EditorGUILayout.Space();
GUILayout.Label("Terrain paint:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
lakePolygon.terrainPaintCarve = EditorGUILayout.CurveField("Terrain paint", lakePolygon.terrainPaintCarve);
int splatNumber = terrain.terrainData.terrainLayers.Length;
if (splatNumber > 0)
{
string[] options = new string[splatNumber];
for (int i = 0; i < splatNumber; i++)
{
options[i] = i + " - ";
if (terrain.terrainData.terrainLayers[i].diffuseTexture != null)
{
options[i] += terrain.terrainData.terrainLayers[i].diffuseTexture.name;
}
}
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Splat id:");
lakePolygon.currentSplatMap = EditorGUILayout.Popup(lakePolygon.currentSplatMap, options);
EditorGUILayout.EndHorizontal();
lakePolygon.noisePaint = EditorGUILayout.Toggle("Add noise", lakePolygon.noisePaint);
if (lakePolygon.noisePaint)
{
EditorGUI.indentLevel++;
lakePolygon.noiseMultiplierInsidePaint = EditorGUILayout.FloatField("Noise multiplier inside", lakePolygon.noiseMultiplierInsidePaint);
lakePolygon.noiseMultiplierOutsidePaint = EditorGUILayout.FloatField("Noise multiplier outside", lakePolygon.noiseMultiplierOutsidePaint);
lakePolygon.noiseSizeXPaint = EditorGUILayout.FloatField("Noise scale X", lakePolygon.noiseSizeXPaint);
lakePolygon.noiseSizeZPaint = EditorGUILayout.FloatField("Noise scale Z", lakePolygon.noiseSizeZPaint);
EditorGUI.indentLevel--;
}
lakePolygon.mixTwoSplatMaps = EditorGUILayout.Toggle("Mix two splat maps", lakePolygon.mixTwoSplatMaps);
if (lakePolygon.mixTwoSplatMaps)
{
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Second splat id:");
lakePolygon.secondSplatMap = EditorGUILayout.Popup(lakePolygon.secondSplatMap, options);
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
}
lakePolygon.addCliffSplatMap = EditorGUILayout.Toggle("Add cliff splatmap", lakePolygon.addCliffSplatMap);
if (lakePolygon.addCliffSplatMap)
{
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Cliff splat id:");
lakePolygon.cliffSplatMap = EditorGUILayout.Popup(lakePolygon.cliffSplatMap, options);
EditorGUILayout.EndHorizontal();
lakePolygon.cliffAngle = EditorGUILayout.FloatField("Cliff angle", lakePolygon.cliffAngle);
lakePolygon.cliffBlend = EditorGUILayout.FloatField("Cliff blend", lakePolygon.cliffBlend);
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Cliff outside splat id:");
lakePolygon.cliffSplatMapOutside = EditorGUILayout.Popup(lakePolygon.cliffSplatMapOutside, options);
EditorGUILayout.EndHorizontal();
lakePolygon.cliffAngleOutside = EditorGUILayout.FloatField("Cliff outside angle", lakePolygon.cliffAngleOutside);
lakePolygon.cliffBlendOutside = EditorGUILayout.FloatField("Cliff outside blend", lakePolygon.cliffBlendOutside);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake curve changed");
foreach (var meshGO in lakePolygon.meshGOs)
{
if (meshGO != null)
{
if (lakePolygon.overrideLakeRender)
meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 5000;
else
meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 2980;
}
}
}
if (GUILayout.Button("Paint Terrain"))
{
lakePolygon.TerrainPaint();
}
}
else
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Terrain has no splatmaps.", MessageType.Info);
}
EditorGUILayout.Space();
GUILayout.Label("Terrain clear foliage:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
lakePolygon.distanceClearFoliage = EditorGUILayout.FloatField("Remove Details Distance", lakePolygon.distanceClearFoliage);
if (GUILayout.Button("Remove Details Foliage"))
{
showCarveTerrain = false;
lakePolygon.TerrainClearTrees();
}
lakePolygon.distanceClearFoliageTrees = EditorGUILayout.FloatField("Remove Trees Distance", lakePolygon.distanceClearFoliageTrees);
if (GUILayout.Button("Remove Trees"))
{
showCarveTerrain = false;
lakePolygon.TerrainClearTrees(false);
}
EditorGUI.indentLevel--;
}
else
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("No Terrain On Scene.", MessageType.Info);
}
}
if (lakePolygon.toolbarInt == 6)
{
FilesManager();
}
if (toolbarNew == 7)
{
EditorGUILayout.Space();
Tips();
}
if (toolbarNew == 8)
{
toolbarNew = lakePolygon.toolbarInt;
string[] guids1 = AssetDatabase.FindAssets("River Auto and Lava Volcano Environment Manual 2019");
Application.OpenURL("file:///" + Application.dataPath.Replace("Assets", "") + AssetDatabase.GUIDToAssetPath(guids1[0]));
}
if (toolbarNew == 9)
{
toolbarNew = lakePolygon.toolbarInt;
Application.OpenURL("https://www.youtube.com/playlist?list=PLWMxYDHySK5PkIlklmHKLYvRWK2sjDYXX");
}
if (toolbarNew == 10)
{
#if VEGETATION_STUDIO
EditorGUILayout.Space();
GUILayout.Label("Vegetation Studio: ", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
lakePolygon.vegetationMaskResolution = EditorGUILayout.Slider("Mask Resolution", lakePolygon.vegetationMaskResolution, 0.1f, 1);
lakePolygon.vegetationMaskPerimeter = EditorGUILayout.FloatField("Vegetation Mask Perimeter", lakePolygon.vegetationMaskPerimeter);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake curve changed");
RegenerateVegetationMask();
}
EditorGUI.indentLevel--;
if (lakePolygon.vegetationMaskArea == null && GUILayout.Button("Add Vegetation Mask Area"))
{
lakePolygon.vegetationMaskArea = lakePolygon.gameObject.AddComponent<VegetationMaskArea>();
RegenerateVegetationMask();
}
if (lakePolygon.vegetationMaskArea != null && GUILayout.Button("Calculate hull outline"))
{
RegenerateVegetationMask();
}
#endif
#if VEGETATION_STUDIO_PRO
EditorGUILayout.Space();
GUILayout.Label("Vegetation Studio Pro: ", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
lakePolygon.vegetationMaskSize = EditorGUILayout.FloatField("Vegetation Mask Size", lakePolygon.vegetationMaskSize);
lakePolygon.vegetationBlendDistance = EditorGUILayout.FloatField("Vegetation Blend Distance", lakePolygon.vegetationBlendDistance);
lakePolygon.biomMaskResolution = EditorGUILayout.Slider("Mask Resolution", lakePolygon.biomMaskResolution, 0.1f, 1);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake curve changed");
RegenerateBiomMask();
}
if (lakePolygon.biomeMaskArea != null)
lakePolygon.refreshMask = EditorGUILayout.Toggle("Auto Refresh Biome Mask", lakePolygon.refreshMask);
if (GUILayout.Button("Add Vegetation Biome Mask Area"))
{
lakePolygon.GeneratePolygon();
if (lakePolygon.biomeMaskArea == null)
{
GameObject maskObject = new GameObject("MyMask");
maskObject.transform.SetParent(lakePolygon.transform);
maskObject.transform.localPosition = Vector3.zero;
lakePolygon.biomeMaskArea = maskObject.AddComponent<BiomeMaskArea>();
}
if (lakePolygon.biomeMaskArea == null)
return;
RegenerateBiomMask(false);
}
#endif
}
lakePolygon.toolbarInt = toolbarNew;
EditorGUILayout.Space();
}
void Tips()
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("\nReflections - Use box projection in reflection probes to get proper render even at river and lake conection.\n", MessageType.Info);
EditorGUILayout.HelpBox(
"\nUse low resolution reflection probes, and only around the water. " + "\nFar clip planes also should be short, you probably only need colors from the surounding world.\n",
MessageType.Info);
EditorGUILayout.HelpBox("\nPut reflection probes behind, in and after dark area (tunel, cave) so you will get exelent result in lighting and reflections.\n", MessageType.Info);
EditorGUILayout.Space();
}
void ResetMaterial()
{
lakePolygon.showFlowMap = false;
lakePolygon.showVertexColors = false;
}
void DrawVertexColorsUI()
{
EditorGUI.BeginChangeCheck();
// Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.drawOnMesh = true;
if (lakePolygon.drawOnMesh)
{
EditorGUILayout.HelpBox("R - Slow Water G - Small Cascade B - Big Cascade A - Opacity", MessageType.Info);
EditorGUILayout.Space();
Color lakePolygonDrawColor = EditorGUILayout.ColorField("Draw color", lakePolygon.drawColor);
if (lakePolygonDrawColor.r != lakePolygon.drawColor.r ||
lakePolygonDrawColor.g != lakePolygon.drawColor.g ||
lakePolygonDrawColor.b != lakePolygon.drawColor.b)
{
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.drawColor = lakePolygonDrawColor;
}
var lakePolygonOpacity = EditorGUILayout.FloatField("Opacity", lakePolygon.opacity);
if (lakePolygonOpacity != lakePolygon.opacity)
{
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.opacity = lakePolygonOpacity;
}
var lakePolygonDrawSize = EditorGUILayout.FloatField("Size", lakePolygon.drawSize);
if (lakePolygonDrawSize != lakePolygon.drawSize)
{
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.drawSize = lakePolygonDrawSize;
}
if (lakePolygon.drawSize < 0)
{
lakePolygon.drawSize = 0;
}
lakePolygon.drawColorR = EditorGUILayout.Toggle("Draw R", lakePolygon.drawColorR);
lakePolygon.drawColorG = EditorGUILayout.Toggle("Draw G", lakePolygon.drawColorG);
lakePolygon.drawColorB = EditorGUILayout.Toggle("Draw B", lakePolygon.drawColorB);
lakePolygon.drawColorA = EditorGUILayout.Toggle("Draw A", lakePolygon.drawColorA);
EditorGUILayout.Space();
lakePolygon.drawOnMultiple = EditorGUILayout.Toggle("Draw on multiple rivers", lakePolygon.drawOnMultiple);
}
EditorGUILayout.Space();
if (!lakePolygon.showVertexColors)
{
if (GUILayout.Button("Show vertex colors"))
{
if (!lakePolygon.showFlowMap && !lakePolygon.showVertexColors)
lakePolygon.oldMaterial = lakePolygon.GetComponent<MeshRenderer>().sharedMaterial;
ResetMaterial();
lakePolygon.GetComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("NatureManufacture Shaders/Debug/Vertex color"));
lakePolygon.showVertexColors = true;
}
}
else
{
if (GUILayout.Button("Hide vertex colors"))
{
ResetMaterial();
lakePolygon.GetComponent<MeshRenderer>().sharedMaterial = lakePolygon.oldMaterial;
lakePolygon.showVertexColors = false;
}
}
if (GUILayout.Button("Reset vertex colors") && EditorUtility.DisplayDialog("Reset vertex colors?",
"Are you sure you want to reset f vertex colors?", "Yes", "No"))
{
lakePolygon.colors = null;
lakePolygon.GeneratePolygon();
#if VEGETATION_STUDIO_PRO
RegenerateBiomMask();
#endif
}
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake changed");
}
}
void DrawFlowColorsUI()
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("Sharp gradient could generate bugged effect. Keep flow changes smooth.", MessageType.Info);
GUILayout.Label("Flow Map Manual: ", EditorStyles.boldLabel);
lakePolygon.drawOnMeshFlowMap = true;
if (lakePolygon.drawOnMeshFlowMap)
{
EditorGUI.BeginChangeCheck();
Undo.RecordObject(lakePolygon, "Lake changed");
EditorGUILayout.Space();
lakePolygon.flowSpeed = EditorGUILayout.Slider("Flow U Speed", lakePolygon.flowSpeed, -1, 1);
lakePolygon.flowDirection = EditorGUILayout.Slider("Flow V Speed", lakePolygon.flowDirection, -1, 1);
lakePolygon.opacity = EditorGUILayout.FloatField("Opacity", lakePolygon.opacity);
lakePolygon.drawSize = EditorGUILayout.FloatField("Size", lakePolygon.drawSize);
if (lakePolygon.drawSize < 0)
{
lakePolygon.drawSize = 0;
}
EditorGUILayout.Space();
lakePolygon.drawOnMultiple = EditorGUILayout.Toggle("Draw on multiple rivers", lakePolygon.drawOnMultiple);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake changed");
}
}
EditorGUILayout.Space();
if (!lakePolygon.showFlowMap)
{
if (GUILayout.Button("Show flow directions"))
{
if (!lakePolygon.showFlowMap && !lakePolygon.showVertexColors)
lakePolygon.oldMaterial = lakePolygon.GetComponent<MeshRenderer>().sharedMaterial;
ResetMaterial();
lakePolygon.GetComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("NatureManufacture Shaders/Debug/Flowmap Direction"));
lakePolygon.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_Direction", Resources.Load<Texture2D>("Debug_Arrow"));
lakePolygon.showFlowMap = true;
}
if (GUILayout.Button("Show flow smoothness"))
{
if (!lakePolygon.showFlowMap && !lakePolygon.showVertexColors)
lakePolygon.oldMaterial = lakePolygon.GetComponent<MeshRenderer>().sharedMaterial;
ResetMaterial();
lakePolygon.GetComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("NatureManufacture Shaders/Debug/FlowMapUV4"));
lakePolygon.showFlowMap = true;
}
}
if (lakePolygon.showFlowMap)
{
if (GUILayout.Button("Hide flow"))
{
ResetMaterial();
lakePolygon.GetComponent<MeshRenderer>().sharedMaterial = lakePolygon.oldMaterial;
}
}
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
Undo.RecordObject(lakePolygon, "Lake changed");
GUILayout.Label("Flow Map Automatic: ", EditorStyles.boldLabel);
lakePolygon.automaticFlowMapScale = EditorGUILayout.FloatField("Automatic speed", lakePolygon.automaticFlowMapScale);
lakePolygon.noiseflowMap = EditorGUILayout.Toggle("Add noise", lakePolygon.noiseflowMap);
if (lakePolygon.noiseflowMap)
{
EditorGUI.indentLevel++;
lakePolygon.noiseMultiplierflowMap = EditorGUILayout.FloatField("Noise multiplier inside", lakePolygon.noiseMultiplierflowMap);
lakePolygon.noiseSizeXflowMap = EditorGUILayout.FloatField("Noise scale X", lakePolygon.noiseSizeXflowMap);
lakePolygon.noiseSizeZflowMap = EditorGUILayout.FloatField("Noise scale Z", lakePolygon.noiseSizeZflowMap);
EditorGUI.indentLevel--;
}
if (GUILayout.Button("Reset flow to automatic") && EditorUtility.DisplayDialog("Reset flow to automatic?",
"Are you sure you want to reset flow to automatic?", "Yes", "No"))
{
lakePolygon.overrideFlowMap = false;
lakePolygon.GeneratePolygon();
#if VEGETATION_STUDIO_PRO
RegenerateBiomMask();
#endif
}
EditorGUILayout.Space();
GUILayout.Label("Flow Map Physic: ", EditorStyles.boldLabel);
lakePolygon.floatSpeed = EditorGUILayout.FloatField("Float speed", lakePolygon.floatSpeed);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake changed");
if (!lakePolygon.overrideFlowMap)
lakePolygon.GeneratePolygon();
}
}
void PointsUI()
{
EditorGUI.BeginChangeCheck();
if (GUILayout.Button(new GUIContent("Remove all points", "Removes all points")))
{
lakePolygon.RemovePoints();
lakePolygon.meshfilter.sharedMesh = null;
}
for (int i = 0; i < lakePolygon.points.Count; i++)
{
GUILayout.Label("Point: " + i.ToString(), EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
lakePolygon.points[i] = EditorGUILayout.Vector3Field("", lakePolygon.points[i]);
if (GUILayout.Button(new GUIContent("A", "Add point after this point"), GUILayout.MaxWidth(20)))
{
lakePolygon.AddPointAfter(i);
lakePolygon.GeneratePolygon();
}
if (GUILayout.Button(new GUIContent("R", "Remove this Point"), GUILayout.MaxWidth(20)))
{
lakePolygon.RemovePoint(i);
lakePolygon.GeneratePolygon();
}
if (GUILayout.Toggle(selectedPosition == i, new GUIContent("S", "Select point"), "Button", GUILayout.MaxWidth(20)))
{
selectedPosition = i;
}
else if (selectedPosition == i)
{
selectedPosition = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(lakePolygon, "Lake changed");
lakePolygon.GeneratePolygon();
}
}
#if VEGETATION_STUDIO_PRO
void RegenerateBiomMask(bool checkAuto = true)
{
if (checkAuto && !lakePolygon.refreshMask)
return;
if (lakePolygon.biomeMaskArea == null)
return;
lakePolygon.biomeMaskArea.BiomeType = BiomeType.Underwater;
List<Vector3> worldspacePointList = new List<Vector3>();
for (int i = 0; i < lakePolygon.splinePoints.Count; i += (int)(1 / (float)lakePolygon.biomMaskResolution))
{
Vector3 position = lakePolygon.transform.TransformPoint(lakePolygon.splinePoints[i])
+ (lakePolygon.transform.TransformPoint(lakePolygon.splinePoints[i]) - lakePolygon.transform.position).normalized * lakePolygon.vegetationMaskSize;
worldspacePointList.Add(position);
}
lakePolygon.biomeMaskArea.ClearNodes();
for (var i = 0; i <= worldspacePointList.Count - 1; i++)
{
lakePolygon.biomeMaskArea.AddNodeToEnd(worldspacePointList[i]);
}
//these have default values but you can set them if you want a different default setting
lakePolygon.biomeMaskArea.BlendDistance = lakePolygon.vegetationBlendDistance;
lakePolygon.biomeMaskArea.NoiseScale = 5;
lakePolygon.biomeMaskArea.UseNoise = true;
//These 3 curves holds the blend curves for vegetation and textures. they have default values;
//biomeMaskArea.BlendCurve;
//biomeMaskArea.InverseBlendCurve;
//biomeMaskArea.TextureBlendCurve;
if (lakePolygon.currentProfile != null)
{
lakePolygon.biomeMaskArea.BiomeType = (BiomeType)lakePolygon.currentProfile.biomeType;
}
else
lakePolygon.biomeMaskArea.BiomeType = BiomeType.River;
lakePolygon.biomeMaskArea.UpdateBiomeMask();
}
#endif
#if VEGETATION_STUDIO
private void RegenerateVegetationMask()
{
if (lakePolygon.vegetationMaskArea == null)
return;
lakePolygon.vegetationMaskArea.AdditionalGrassPerimiterMax = lakePolygon.vegetationMaskPerimeter;
lakePolygon.vegetationMaskArea.AdditionalLargeObjectPerimiterMax = lakePolygon.vegetationMaskPerimeter;
lakePolygon.vegetationMaskArea.AdditionalObjectPerimiterMax = lakePolygon.vegetationMaskPerimeter;
lakePolygon.vegetationMaskArea.AdditionalPlantPerimiterMax = lakePolygon.vegetationMaskPerimeter;
lakePolygon.vegetationMaskArea.AdditionalTreePerimiterMax = lakePolygon.vegetationMaskPerimeter;
lakePolygon.vegetationMaskArea.GenerateHullNodes(lakePolygon.vegetationMaskArea.ReductionTolerance);
lakePolygon.GeneratePolygon();
List<Vector3> worldspacePointList = new List<Vector3>();
for (int i = 0; i < lakePolygon.splinePoints.Count; i += (int)(1 / (float)lakePolygon.vegetationMaskResolution))
{
Vector3 position = lakePolygon.transform.TransformPoint(lakePolygon.splinePoints[i])
+ (lakePolygon.transform.TransformPoint(lakePolygon.splinePoints[i]) - lakePolygon.transform.position).normalized * lakePolygon.vegetationMaskPerimeter;
worldspacePointList.Add(position);
}
lakePolygon.vegetationMaskArea.ClearNodes();
for (var i = 0; i <= worldspacePointList.Count - 1; i++)
{
lakePolygon.vegetationMaskArea.AddNodeToEnd(worldspacePointList[i]);
}
lakePolygon.vegetationMaskArea.UpdateVegetationMask();
}
#endif
void FilesManager()
{
if (GUILayout.Button("Save points to csv file"))
{
PointsToFile();
}
if (GUILayout.Button("Load points from csv file"))
{
PointsFromFile();
}
}
void DrawOnVertexColors()
{
if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
{
Undo.RegisterCompleteObjectUndo(lakePolygon, "Painted");
}
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
// Camera sceneCamera = SceneView.lastActiveSceneView.camera;
HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
// Vector2 mousePos = Event.current.mousePosition;
// mousePos.y = Screen.height - mousePos.y - 40;
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); // sceneCamera.ScreenPointToRay(mousePos);
List<MeshCollider> meshColliders = new List<MeshCollider>();
foreach (var item in lakes)
{
meshColliders.Add(item.gameObject.AddComponent<MeshCollider>());
}
RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity);
GameObject go = null;
Vector3 hitPosition = Vector3.zero;
Vector3 hitNormal = Vector3.zero;
LakePolygon hitedSpline = null;
if (hits.Length > 0)
{
foreach (var hit in hits)
{
if (hit.collider is MeshCollider)
{
go = hit.collider.gameObject;
hitedSpline = go.GetComponent<LakePolygon>();
if (hitedSpline != null && (lakePolygon.drawOnMultiple || hitedSpline == lakePolygon))
{
hitPosition = hit.point;
hitNormal = hit.normal;
break;
}
else
go = null;
}
}
}
foreach (var item in meshColliders)
{
if (item != null)
DestroyImmediate(item);
}
if (go != null)
{
Handles.color = new Color(lakePolygon.drawColor.r, lakePolygon.drawColor.g, lakePolygon.drawColor.b, 1);
Handles.DrawLine(hitPosition, hitPosition + hitNormal * 2);
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
lakePolygon.drawSize,
EventType.Repaint
);
Handles.color = Color.black;
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
lakePolygon.drawSize - 0.1f,
EventType.Repaint
);
if (!(Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) || Event.current.button != 0)
return;
MeshFilter meshFilter = hitedSpline.GetComponent<MeshFilter>();
if (meshFilter.sharedMesh != null)
{
Mesh mesh = meshFilter.sharedMesh;
if (hitedSpline.colors.Length == 0)
hitedSpline.colors = new Color[mesh.vertices.Length];
int length = mesh.vertices.Length;
float dist = 0;
hitPosition -= hitedSpline.transform.position;
Vector3[] vertices = mesh.vertices;
Color[] colors = hitedSpline.colors;
for (int i = 0; i < length; i++)
{
dist = Vector3.Distance(hitPosition, vertices[i]);
if (dist < hitedSpline.drawSize)
{
if (Event.current.shift)
{
if (lakePolygon.drawColorR)
colors[i].r = Mathf.Lerp(colors[i].r, 0, lakePolygon.opacity);
if (lakePolygon.drawColorG)
colors[i].g = Mathf.Lerp(colors[i].g, 0, lakePolygon.opacity);
if (lakePolygon.drawColorB)
colors[i].b = Mathf.Lerp(colors[i].b, 0, lakePolygon.opacity);
if (lakePolygon.drawColorA)
colors[i].a = Mathf.Lerp(colors[i].a, 1, lakePolygon.opacity);
}
else
{
if (lakePolygon.drawColorR)
colors[i].r = Mathf.Lerp(colors[i].r, lakePolygon.drawColor.r, lakePolygon.opacity);
if (lakePolygon.drawColorG)
colors[i].g = Mathf.Lerp(colors[i].g, lakePolygon.drawColor.g, lakePolygon.opacity);
if (lakePolygon.drawColorB)
colors[i].b = Mathf.Lerp(colors[i].b, lakePolygon.drawColor.b, lakePolygon.opacity);
if (lakePolygon.drawColorA)
colors[i].a = Mathf.Lerp(colors[i].a, lakePolygon.drawColor.a, lakePolygon.opacity);
}
}
}
mesh.colors = colors;
meshFilter.sharedMesh = mesh;
}
}
}
void DrawOnFlowMap()
{
if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
{
Undo.RegisterCompleteObjectUndo(lakePolygon, "Painted");
}
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
//Camera sceneCamera = SceneView.lastActiveSceneView.camera;
// Vector2 mousePos = Event.current.mousePosition;
// mousePos.y = Screen.height - mousePos.y - 40;
// Ray ray = sceneCamera.ScreenPointToRay(mousePos);
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
List<MeshCollider> meshColliders = new List<MeshCollider>();
foreach (var item in lakes)
{
meshColliders.Add(item.gameObject.AddComponent<MeshCollider>());
}
RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity);
GameObject go = null;
Vector3 hitPosition = Vector3.zero;
Vector3 hitNormal = Vector3.zero;
LakePolygon hitedSpline = null;
if (hits.Length > 0)
{
foreach (var hit in hits)
{
if (hit.collider is MeshCollider)
{
go = hit.collider.gameObject;
hitedSpline = go.GetComponent<LakePolygon>();
if (hitedSpline != null && (lakePolygon.drawOnMultiple || hitedSpline == lakePolygon))
{
hitPosition = hit.point;
hitNormal = hit.normal;
break;
}
else
go = null;
}
}
}
foreach (var item in meshColliders)
{
if (item != null)
DestroyImmediate(item);
}
if (go != null)
{
Handles.color = new Color(lakePolygon.flowDirection, lakePolygon.flowSpeed, 0, 1);
Handles.DrawLine(hitPosition, hitPosition + hitNormal * 2);
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
lakePolygon.drawSize,
EventType.Repaint
);
Handles.color = Color.black;
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
lakePolygon.drawSize - 0.1f,
EventType.Repaint
);
if (!(Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) || Event.current.button != 0)
return;
hitedSpline.overrideFlowMap = true;
MeshFilter meshFilter = hitedSpline.GetComponent<MeshFilter>();
if (meshFilter.sharedMesh != null)
{
Mesh mesh = meshFilter.sharedMesh;
List<Vector2> colorsFlowMap = hitedSpline.colorsFlowMap;
int length = mesh.vertices.Length;
float dist = 0;
float distValue = 0;
hitPosition -= hitedSpline.transform.position;
Vector3[] vertices = mesh.vertices;
for (int i = 0; i < length; i++)
{
dist = Vector3.Distance(hitPosition, vertices[i]);
if (dist < lakePolygon.drawSize)
{
distValue = (lakePolygon.drawSize - dist) / (float) lakePolygon.drawSize;
if (Event.current.shift)
{
colorsFlowMap[i] = Vector2.Lerp(colorsFlowMap[i], new Vector2(0, 0), lakePolygon.opacity);
}
else
{
colorsFlowMap[i] = Vector2.Lerp(colorsFlowMap[i], new Vector2(lakePolygon.flowDirection, lakePolygon.flowSpeed), lakePolygon.opacity * distValue);
}
}
}
mesh.uv4 = colorsFlowMap.ToArray();
hitedSpline.colorsFlowMap = colorsFlowMap;
meshFilter.sharedMesh = mesh;
}
}
}
bool dragged;
protected virtual void OnSceneGUIInvoke(SceneView sceneView)
{
//Debug.Log(target.GetType().Name);
if (lakePolygon == null)
lakePolygon = (LakePolygon) target;
if (lakePolygon == null)
return;
Color baseColor = Handles.color;
int controlId = GUIUtility.GetControlID(FocusType.Passive);
if (lakePolygon != null)
if (lakePolygon.drawOnMesh || lakePolygon.drawOnMeshFlowMap)
{
Tools.current = Tool.None;
if (lakePolygon.meshfilter != null)
{
Handles.color = Color.magenta;
Vector3[] vertices = lakePolygon.meshfilter.sharedMesh.vertices;
Vector2[] uv4 = lakePolygon.meshfilter.sharedMesh.uv4;
Vector3[] normals = lakePolygon.meshfilter.sharedMesh.normals;
Quaternion up = Quaternion.Euler(90, 0, 0);
for (int i = 0; i < vertices.Length; i += 5)
{
Vector3 item = vertices[i];
Vector3 handlePos = lakePolygon.transform.TransformPoint(item);
if (lakePolygon.drawOnMesh)
Handles.RectangleHandleCap(0, handlePos, up, 0.05f, EventType.Repaint);
}
}
if (lakePolygon.drawOnMesh)
DrawOnVertexColors();
else
DrawOnFlowMap();
return;
}
if (lakePolygon.lockHeight && lakePolygon.points.Count > 1)
{
for (int i = 1; i < lakePolygon.points.Count; i++)
{
Vector3 vec = lakePolygon.points[i];
vec.y = lakePolygon.points[0].y;
lakePolygon.points[i] = vec;
}
}
{
Vector3[] points = new Vector3[lakePolygon.splinePoints.Count];
for (int i = 0; i < lakePolygon.splinePoints.Count; i++)
{
points[i] = lakePolygon.splinePoints[i] + lakePolygon.transform.position;
}
Handles.color = Color.white;
if (lakePolygon.points.Count > 1)
Handles.DrawPolyLine(points);
if (Event.current.commandName == "UndoRedoPerformed")
{
lakePolygon.GeneratePolygon();
return;
}
if (selectedPosition >= 0 && selectedPosition < lakePolygon.points.Count)
{
Handles.color = Color.red;
Handles.SphereHandleCap(0, (Vector3) lakePolygon.points[selectedPosition] + lakePolygon.transform.position, Quaternion.identity, 1, EventType.Repaint);
}
if (dragged && Event.current.type == EventType.MouseUp)
{
lakePolygon.GeneratePolygon();
}
int controlPointToDelete = -1;
for (int j = 0; j < lakePolygon.points.Count; j++)
{
EditorGUI.BeginChangeCheck();
Vector3 handlePos = (Vector3) lakePolygon.points[j] + lakePolygon.transform.position;
GUIStyle style = new GUIStyle();
style.normal.textColor = Color.red;
Vector3 screenPoint = Camera.current.WorldToScreenPoint(handlePos);
if (screenPoint.z > 0)
{
Handles.Label(handlePos + Vector3.up * HandleUtility.GetHandleSize(handlePos), "Point: " + j.ToString(), style);
}
if (Event.current.control && Event.current.shift)
{
int id = GUIUtility.GetControlID(FocusType.Passive);
if (HandleUtility.nearestControl == id)
{
Handles.color = Color.white;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
controlPointToDelete = j;
}
else
Handles.color = Handles.xAxisColor;
float size = 0.6f;
size = HandleUtility.GetHandleSize(handlePos) * size;
if (Event.current.type == EventType.Repaint)
{
Handles.SphereHandleCap(id, (Vector3) lakePolygon.points[j] + lakePolygon.transform.position, Quaternion.identity, size, EventType.Repaint);
}
else if (Event.current.type == EventType.Layout)
{
Handles.SphereHandleCap(id, (Vector3) lakePolygon.points[j] + lakePolygon.transform.position, Quaternion.identity, size, EventType.Layout);
}
}
else if (Tools.current == Tool.Move)
{
float size = 0.6f;
size = HandleUtility.GetHandleSize(handlePos) * size;
Handles.color = Handles.xAxisColor;
Vector3 pos = Handles.Slider((Vector3) lakePolygon.points[j] + lakePolygon.transform.position, Vector3.right, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position;
if (!lakePolygon.lockHeight || lakePolygon.points.Count == 1)
{
Handles.color = Handles.yAxisColor;
pos = Handles.Slider((Vector3) pos + lakePolygon.transform.position, Vector3.up, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position;
}
Handles.color = Handles.zAxisColor;
pos = Handles.Slider((Vector3) pos + lakePolygon.transform.position, Vector3.forward, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position;
Vector3 halfPos = (Vector3.right + Vector3.forward) * size * 0.3f;
Handles.color = Handles.yAxisColor;
pos = Handles.Slider2D((Vector3) pos + lakePolygon.transform.position + halfPos, Vector3.up, Vector3.right, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) -
lakePolygon.transform.position - halfPos;
halfPos = (Vector3.right + Vector3.up) * size * 0.3f;
if (!lakePolygon.lockHeight || lakePolygon.points.Count == 1)
{
Handles.color = Handles.zAxisColor;
pos = Handles.Slider2D((Vector3) pos + lakePolygon.transform.position + halfPos, Vector3.forward, Vector3.right, Vector3.up, size * 0.3f, Handles.RectangleHandleCap, 0.01f) -
lakePolygon.transform.position - halfPos;
halfPos = (Vector3.up + Vector3.forward) * size * 0.3f;
Handles.color = Handles.xAxisColor;
pos = Handles.Slider2D((Vector3) pos + lakePolygon.transform.position + halfPos, Vector3.right, Vector3.up, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) -
lakePolygon.transform.position - halfPos;
}
lakePolygon.points[j] = pos;
}
if (EditorGUI.EndChangeCheck())
{
dragged = true;
Undo.RecordObject(lakePolygon, "Change Position");
lakePolygon.GeneratePolygon(true);
#if VEGETATION_STUDIO
RegenerateVegetationMask();
#endif
#if VEGETATION_STUDIO_PRO
RegenerateBiomMask();
#endif
}
}
if (controlPointToDelete >= 0)
{
Undo.RecordObject(lakePolygon, "Remove point");
Undo.RecordObject(lakePolygon.transform, "Remove point");
lakePolygon.RemovePoint(controlPointToDelete);
lakePolygon.GeneratePolygon();
GUIUtility.hotControl = controlId;
Event.current.Use();
HandleUtility.Repaint();
controlPointToDelete = -1;
}
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.control)
{
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Undo.RecordObject(lakePolygon, "Add point");
Undo.RecordObject(lakePolygon.transform, "Add point");
Vector3 position = hit.point - lakePolygon.transform.position;
lakePolygon.AddPoint(position);
lakePolygon.GeneratePolygon();
#if VEGETATION_STUDIO
RegenerateVegetationMask();
#endif
#if VEGETATION_STUDIO_PRO
RegenerateBiomMask();
#endif
GUIUtility.hotControl = controlId;
Event.current.Use();
HandleUtility.Repaint();
}
}
if (!Event.current.control && Event.current.shift && lakePolygon.points.Count > 1)
{
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
int idMin = -1;
float distanceMin = float.MaxValue;
for (int j = 0; j < lakePolygon.points.Count; j++)
{
Vector3 handlePos = (Vector3) lakePolygon.points[j] + lakePolygon.transform.position;
float pointDist = Vector3.Distance(hit.point, handlePos);
if (pointDist < distanceMin)
{
distanceMin = pointDist;
idMin = j;
}
}
Vector3 posOne = (Vector3) lakePolygon.points[idMin] + lakePolygon.transform.position;
Vector3 posTwo;
Vector3 posPrev = (Vector3) lakePolygon.points[lakePolygon.ClampListPos(idMin - 1)] + lakePolygon.transform.position;
Vector3 posNext = (Vector3) lakePolygon.points[lakePolygon.ClampListPos(idMin + 1)] + lakePolygon.transform.position;
if (Vector3.Distance(hit.point, posPrev) > Vector3.Distance(hit.point, posNext))
posTwo = posNext;
else
{
posTwo = posPrev;
idMin = lakePolygon.ClampListPos(idMin - 1);
}
Handles.color = Handles.xAxisColor;
Handles.DrawLine(hit.point, posOne);
Handles.DrawLine(hit.point, posTwo);
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Undo.RecordObject(lakePolygon, "Add point");
Undo.RecordObject(lakePolygon.transform, "Add point");
Vector4 position = hit.point - lakePolygon.transform.position;
lakePolygon.AddPointAfter(idMin);
lakePolygon.ChangePointPosition(idMin + 1, position);
lakePolygon.GeneratePolygon();
GUIUtility.hotControl = controlId;
Event.current.Use();
HandleUtility.Repaint();
}
}
}
if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.control)
{
GUIUtility.hotControl = 0;
}
if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.shift)
{
GUIUtility.hotControl = 0;
}
}
}
bool CheckProfileChange()
{
if (lakePolygon.currentProfile == null)
return false;
//if (lakePolygon.terrainCarve != lakePolygon.currentProfile.terrainCarve)
// return true;
if (lakePolygon.distSmooth != lakePolygon.currentProfile.distSmooth)
return true;
if (lakePolygon.uvScale != lakePolygon.currentProfile.uvScale)
return true;
if (lakePolygon.terrainSmoothMultiplier != lakePolygon.currentProfile.terrainSmoothMultiplier)
return true;
//if (lakePolygon.terrainPaintCarve != lakePolygon.currentProfile.terrainPaintCarve)
// return true;
if (lakePolygon.currentSplatMap != lakePolygon.currentProfile.currentSplatMap)
return true;
if (lakePolygon.maximumTriangleSize != lakePolygon.currentProfile.maximumTriangleSize)
return true;
if (lakePolygon.traingleDensity != lakePolygon.currentProfile.traingleDensity)
return true;
if (lakePolygon.currentProfile.receiveShadows != lakePolygon.receiveShadows)
return true;
if (lakePolygon.currentProfile.shadowCastingMode != lakePolygon.shadowCastingMode)
return true;
if (lakePolygon.automaticFlowMapScale != lakePolygon.currentProfile.automaticFlowMapScale)
return true;
if (lakePolygon.noiseflowMap != lakePolygon.currentProfile.noiseflowMap)
return true;
if (lakePolygon.noiseMultiplierflowMap != lakePolygon.currentProfile.noiseMultiplierflowMap)
return true;
if (lakePolygon.noiseSizeXflowMap != lakePolygon.currentProfile.noiseSizeXflowMap)
return true;
if (lakePolygon.noiseSizeZflowMap != lakePolygon.currentProfile.noiseSizeZflowMap)
return true;
if (lakePolygon.currentProfile.noisePaint != lakePolygon.noisePaint)
return true;
if (lakePolygon.currentProfile.noiseMultiplierInsidePaint != lakePolygon.noiseMultiplierInsidePaint)
return true;
if (lakePolygon.currentProfile.noiseMultiplierOutsidePaint != lakePolygon.noiseMultiplierOutsidePaint)
return true;
if (lakePolygon.currentProfile.noiseSizeXPaint != lakePolygon.noiseSizeXPaint)
return true;
if (lakePolygon.currentProfile.noiseSizeZPaint != lakePolygon.noiseSizeZPaint)
return true;
if (lakePolygon.currentProfile.mixTwoSplatMaps != lakePolygon.mixTwoSplatMaps)
return true;
if (lakePolygon.currentProfile.secondSplatMap != lakePolygon.secondSplatMap)
return true;
if (lakePolygon.currentProfile.addCliffSplatMap != lakePolygon.addCliffSplatMap)
return true;
if (lakePolygon.currentProfile.cliffSplatMap != lakePolygon.cliffSplatMap)
return true;
if (lakePolygon.currentProfile.cliffAngle != lakePolygon.cliffAngle)
return true;
if (lakePolygon.currentProfile.cliffBlend != lakePolygon.cliffBlend)
return true;
if (lakePolygon.currentProfile.cliffSplatMapOutside != lakePolygon.cliffSplatMapOutside)
return true;
if (lakePolygon.currentProfile.cliffAngleOutside != lakePolygon.cliffAngleOutside)
return true;
if (lakePolygon.currentProfile.cliffBlendOutside != lakePolygon.cliffBlendOutside)
return true;
if (lakePolygon.currentProfile.distanceClearFoliage != lakePolygon.distanceClearFoliage)
return true;
if (lakePolygon.currentProfile.distanceClearFoliageTrees != lakePolygon.distanceClearFoliageTrees)
return true;
return false;
}
public void ResetToProfile()
{
if (lakePolygon == null)
lakePolygon = (LakePolygon) target;
MeshRenderer ren = lakePolygon.GetComponent<MeshRenderer>();
ren.sharedMaterial = lakePolygon.currentProfile.lakeMaterial;
lakePolygon.terrainCarve = new AnimationCurve(lakePolygon.currentProfile.terrainCarve.keys);
lakePolygon.terrainPaintCarve = new AnimationCurve(lakePolygon.currentProfile.terrainPaintCarve.keys);
// lakePolygon.terrainCarve = lakePolygon.currentProfile.terrainCarve;
lakePolygon.distSmooth = lakePolygon.currentProfile.distSmooth;
lakePolygon.uvScale = lakePolygon.currentProfile.uvScale;
lakePolygon.terrainSmoothMultiplier = lakePolygon.currentProfile.terrainSmoothMultiplier;
// lakePolygon.terrainPaintCarve = lakePolygon.currentProfile.terrainPaintCarve;
lakePolygon.currentSplatMap = lakePolygon.currentProfile.currentSplatMap;
lakePolygon.maximumTriangleSize = lakePolygon.currentProfile.maximumTriangleSize;
lakePolygon.traingleDensity = lakePolygon.currentProfile.traingleDensity;
lakePolygon.receiveShadows = lakePolygon.currentProfile.receiveShadows;
lakePolygon.shadowCastingMode = lakePolygon.currentProfile.shadowCastingMode;
lakePolygon.automaticFlowMapScale = lakePolygon.currentProfile.automaticFlowMapScale;
lakePolygon.noiseflowMap = lakePolygon.currentProfile.noiseflowMap;
lakePolygon.noiseMultiplierflowMap = lakePolygon.currentProfile.noiseMultiplierflowMap;
lakePolygon.noiseSizeXflowMap = lakePolygon.currentProfile.noiseSizeXflowMap;
lakePolygon.noiseSizeZflowMap = lakePolygon.currentProfile.noiseSizeZflowMap;
lakePolygon.noiseCarve = lakePolygon.currentProfile.noiseCarve;
lakePolygon.noiseMultiplierInside = lakePolygon.currentProfile.noiseMultiplierInside;
lakePolygon.noiseMultiplierOutside = lakePolygon.currentProfile.noiseMultiplierOutside;
lakePolygon.noiseSizeX = lakePolygon.currentProfile.noiseSizeX;
lakePolygon.noiseSizeZ = lakePolygon.currentProfile.noiseSizeZ;
lakePolygon.noisePaint = lakePolygon.currentProfile.noisePaint;
lakePolygon.noiseMultiplierInsidePaint = lakePolygon.currentProfile.noiseMultiplierInsidePaint;
lakePolygon.noiseMultiplierOutsidePaint = lakePolygon.currentProfile.noiseMultiplierOutsidePaint;
lakePolygon.noiseSizeXPaint = lakePolygon.currentProfile.noiseSizeXPaint;
lakePolygon.noiseSizeZPaint = lakePolygon.currentProfile.noiseSizeZPaint;
lakePolygon.mixTwoSplatMaps = lakePolygon.currentProfile.mixTwoSplatMaps;
lakePolygon.secondSplatMap = lakePolygon.currentProfile.secondSplatMap;
lakePolygon.addCliffSplatMap = lakePolygon.currentProfile.addCliffSplatMap;
lakePolygon.cliffSplatMap = lakePolygon.currentProfile.cliffSplatMap;
lakePolygon.cliffAngle = lakePolygon.currentProfile.cliffAngle;
;
lakePolygon.cliffBlend = lakePolygon.currentProfile.cliffBlend;
lakePolygon.cliffSplatMapOutside = lakePolygon.currentProfile.cliffSplatMapOutside;
lakePolygon.cliffAngleOutside = lakePolygon.currentProfile.cliffAngleOutside;
lakePolygon.cliffBlendOutside = lakePolygon.currentProfile.cliffBlendOutside;
lakePolygon.distanceClearFoliage = lakePolygon.currentProfile.distanceClearFoliage;
lakePolygon.distanceClearFoliageTrees = lakePolygon.currentProfile.distanceClearFoliageTrees;
lakePolygon.oldProfile = lakePolygon.currentProfile;
}
public void PointsToFile()
{
var path = EditorUtility.SaveFilePanelInProject(
"Save Lake Points",
lakePolygon.name + "Points.csv",
"csv",
"Save Spline " + lakePolygon.name + " Points in CSV");
if (string.IsNullOrEmpty(path))
return;
string fileData = "";
foreach (Vector4 v in lakePolygon.points)
{
fileData += v.x + ";" + v.y + ";" + v.z + ";" + v.w + "\n";
}
if (fileData.Length > 0)
fileData.Remove(fileData.Length - 1, 1);
// Debug.Log(fileData);
File.WriteAllText(path, fileData);
}
public void PointsFromFile()
{
string path = EditorUtility.OpenFilePanel("Read Lake Points from CSV", Application.dataPath, "csv");
if (string.IsNullOrEmpty(path))
return;
string fileData = File.ReadAllText(path);
string[] lines = fileData.Split(new char[] {'\n'}, System.StringSplitOptions.RemoveEmptyEntries);
Vector4[] vectors = new Vector4[lines.Length];
for (int i = 0; i < vectors.Length; i++)
{
string[] values = lines[i].Split(new char[] {';'}, System.StringSplitOptions.RemoveEmptyEntries);
if (values.Length != 4)
Debug.LogError("Wrong file data");
else
{
try
{
vectors[i] = new Vector4(float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3]));
}
catch (System.Exception)
{
Debug.LogError("Wrong file data");
return;
}
}
}
Undo.RecordObject(lakePolygon, "Lake changed");
if (vectors.Length > 0)
{
foreach (var item in vectors)
{
lakePolygon.AddPoint(item);
}
}
}
}