Files
2024-11-20 15:21:28 +01:00

3163 lines
117 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.IO;
using UnityEngine.Rendering;
using System.Linq;
#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(RamSpline)), CanEditMultipleObjects]
public class RamSplineEditor : Editor
{
//Vector2 scrollPos;
RamSpline[] splines;
RamSpline spline;
Texture2D logo;
int selectedPosition = -1;
Vector3 pivotChange = Vector3.zero;
bool terrainShapeShow = false;
List<List<Vector4>> positionArray;
int splitPoint = 1;
Mesh meshTerrain;
public string[] shadowcastingOptions = new string[] { "Off", "On", "TwoSided", "ShadowsOnly" };
public string[] toolbarStrings = new string[] {
"Basic ",
"Points",
"Vertex Color",
"Flow Map",
"Simulate",
"Terrain",
"File Points",
"Tips",
"Manual",
"Video Tutorials"
#if VEGETATION_STUDIO
,
"Vegetation Studio"
#endif
#if VEGETATION_STUDIO_PRO
,
"Vegetation Studio Pro"
#endif
};
//, "Debug" };
// /// <summary>
// /// The button editing style.
// /// </summary>
// GUIStyle buttonEditingStyle;
[MenuItem("GameObject/3D Object/Create River Spline")]
static public void CreateSpline()
{
Selection.activeGameObject = RamSpline.CreateSpline(AssetDatabase.GetBuiltinExtraResource<Material>("Default-Diffuse.mat")).gameObject;
}
void OnEnable()
{
splines = FindObjectsOfType<RamSpline>();
#if VEGETATION_STUDIO
spline = (RamSpline)target;
spline.vegetationMaskArea = spline.gameObject.GetComponent<VegetationMaskArea>();
#endif
SceneView.duringSceneGui -= this.OnSceneGUIInvoke;
SceneView.duringSceneGui += this.OnSceneGUIInvoke;
}
private void OnDisable()
{
if (spline != null && spline.meshGO != null)
DestroyImmediate(spline.meshGO);
SceneView.duringSceneGui -= this.OnSceneGUIInvoke;
}
private void OnDestroy()
{
if (spline != null && spline.meshGO != null)
DestroyImmediate(spline.meshGO);
}
void CheckRotations()
{
bool nan = false;
if (spline.controlPointsRotations == null)
{
spline.controlPointsRotations = new List<Quaternion>();
nan = true;
}
if (spline.controlPoints.Count > spline.controlPointsRotations.Count)
{
nan = true;
for (int i = 0; i < spline.controlPoints.Count - spline.controlPointsRotations.Count; i++)
{
spline.controlPointsRotations.Add(Quaternion.identity);
}
}
for (int i = 0; i < spline.controlPointsRotations.Count; i++)
{
if (float.IsNaN(spline.controlPointsRotations[i].x) || float.IsNaN(spline.controlPointsRotations[i].y) || float.IsNaN(spline.controlPointsRotations[i].z) || float.IsNaN(spline.controlPointsRotations[i].w))
{
spline.controlPointsRotations[i] = Quaternion.identity;
nan = true;
}
if (spline.controlPointsRotations[i].x == 0 && spline.controlPointsRotations[i].y == 0 && spline.controlPointsRotations[i].z == 0 && spline.controlPointsRotations[i].w == 0)
{
spline.controlPointsRotations[i] = Quaternion.identity;
nan = true;
}
spline.controlPointsRotations[i] = Quaternion.Euler(spline.controlPointsRotations[i].eulerAngles);
}
if (nan)
spline.GenerateSpline();
}
public override void OnInspectorGUI()
{
EditorGUILayout.Space();
logo = (Texture2D)Resources.Load("logoRAM");
Color baseCol = GUI.color;
spline = (RamSpline)target;
CheckRotations();
if (spline.controlPoints.Count > spline.controlPointsSnap.Count)
{
for (int i = 0; i < spline.controlPoints.Count - spline.controlPointsSnap.Count; i++)
{
spline.controlPointsSnap.Add(0);
}
}
if (spline.controlPoints.Count > spline.controlPointsMeshCurves.Count)
{
for (int i = 0; i < spline.controlPoints.Count - spline.controlPointsMeshCurves.Count; i++)
{
spline.controlPointsMeshCurves.Add(new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 0) }));
}
}
if (spline.controlPoints.Count > spline.controlPointsOrientation.Count)
spline.GenerateSpline();
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);
EditorGUI.BeginChangeCheck();
// GUILayout.Toolbar(spline.toolbarInt, toolbarStrings);
int toolbarNew = GUILayout.SelectionGrid(spline.toolbarInt, toolbarStrings, 3, GUILayout.Height(125));
if (toolbarNew == 8)
{
toolbarNew = spline.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 = spline.toolbarInt;
Application.OpenURL("https://www.youtube.com/playlist?list=PLWMxYDHySK5PkIlklmHKLYvRWK2sjDYXX");
}
if (spline.toolbarInt != toolbarNew)
{
if (spline.meshGO != null)
DestroyImmediate(spline.meshGO);
}
spline.toolbarInt = toolbarNew;
EditorGUILayout.Space();
spline.drawOnMesh = false;
spline.drawOnMeshFlowMap = false;
if (spline.showFlowMap)
{
if (spline.uvRotation)
spline.GetComponent<MeshRenderer>().sharedMaterial.SetFloat("_RotateUV", 1);
else
spline.GetComponent<MeshRenderer>().sharedMaterial.SetFloat("_RotateUV", 0);
}
if (spline.transform.eulerAngles.magnitude != 0 || spline.transform.localScale.x != 1 || spline.transform.localScale.y != 1 || spline.transform.localScale.z != 1)
EditorGUILayout.HelpBox("River should have scale (1,1,1) and rotation (0,0,0) during edit!", MessageType.Error);
if (spline.toolbarInt == 0)
{
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);
EditorGUI.indentLevel++;
AddPointAtEnd();
EditorGUI.indentLevel--;
EditorGUILayout.Space();
MeshSettings();
GUILayout.Label("UV settings:", EditorStyles.boldLabel);
if (spline.beginningSpline == null && spline.endingSpline == null)
{
spline.uvScale = EditorGUILayout.FloatField("UV scale (texture tiling)", spline.uvScale);
}
else
{
spline.uvScaleOverride = EditorGUILayout.Toggle("Parent UV scale override", spline.uvScaleOverride);
if (!spline.uvScaleOverride)
{
if (spline.beginningSpline != null)
spline.uvScale = spline.beginningSpline.uvScale;
if (spline.endingSpline != null)
spline.uvScale = spline.endingSpline.uvScale;
GUI.enabled = false;
}
spline.uvScale = EditorGUILayout.FloatField("UV scale (texture tiling)", spline.uvScale);
GUI.enabled = true;
}
spline.invertUVDirection = EditorGUILayout.Toggle("Invert UV direction", spline.invertUVDirection);
spline.uvRotation = EditorGUILayout.Toggle("Rotate UV", spline.uvRotation);
GUILayout.Label("Lightning settings:", EditorStyles.boldLabel);
spline.receiveShadows = EditorGUILayout.Toggle("Receive Shadows", spline.receiveShadows);
spline.shadowCastingMode = (ShadowCastingMode)EditorGUILayout.EnumPopup("Shadow Casting Mode", spline.shadowCastingMode);
EditorGUILayout.Space();
//SetMaterials ();
EditorGUILayout.Space();
ParentingSplineUI();
EditorGUILayout.Space();
EditorGUILayout.Space();
GUILayout.Label("Mesh spliting:", EditorStyles.boldLabel);
spline.generateMeshParts = EditorGUILayout.Toggle("Split mesh into submeshes", spline.generateMeshParts);
if (spline.generateMeshParts)
{
spline.meshPartsCount = EditorGUILayout.IntSlider("Parts", spline.meshPartsCount, 2, (int)((1 / (float)spline.traingleDensity) * (spline.controlPoints.Count - 1) * 0.5));
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Split spline into 2 splines:");
EditorGUI.indentLevel++;
if (spline.controlPoints.Count > 2)
{
splitPoint = EditorGUILayout.IntSlider("Split point", splitPoint, 1, spline.controlPoints.Count - 1);
if (GUILayout.Button("Split spline"))
{
SplitRiver(splitPoint);
}
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
GUILayout.Label("Object settings:", EditorStyles.boldLabel);
EditorGUILayout.Space();
if (GUILayout.Button("Set object pivot to center"))
{
Vector3 center = spline.meshfilter.sharedMesh.bounds.center;
ChangePivot(center);
}
EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("Set object pivot position"))
{
ChangePivot(pivotChange - spline.transform.position);
}
pivotChange = EditorGUILayout.Vector3Field("", pivotChange);
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.Space();
if (GUILayout.Button(new GUIContent("Regenerate spline", "Racalculates whole mesh")))
{
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
spline.generateOnStart = EditorGUILayout.Toggle("Regenerate on Start", spline.generateOnStart);
EditorGUILayout.Space();
if (GUILayout.Button("Export as mesh"))
{
string path = EditorUtility.SaveFilePanelInProject("Save river mesh", "", "asset", "Save river mesh");
if (path.Length != 0 && spline.meshfilter.sharedMesh != null)
{
AssetDatabase.CreateAsset(spline.meshfilter.sharedMesh, path);
AssetDatabase.Refresh();
spline.GenerateSpline();
}
}
EditorGUILayout.Space();
GUILayout.Label("Debug Settings: ", EditorStyles.boldLabel);
spline.debug = EditorGUILayout.Toggle("Show debug gizmos", spline.debug);
if (spline.debug)
{
EditorGUI.indentLevel++;
// spline.debugMesh = EditorGUILayout.Toggle("Debug Mesh", spline.debugMesh);
spline.distanceToDebug = EditorGUILayout.DelayedFloatField("Debug distance", spline.distanceToDebug);
spline.debugTangents = EditorGUILayout.Toggle("Show tangents", spline.debugTangents);
// spline.debugBitangent = EditorGUILayout.Toggle("Show bitangents", spline.debugBitangent);
spline.debugNormals = EditorGUILayout.Toggle("Show normals", spline.debugNormals);
spline.debugFlowmap = EditorGUILayout.Toggle("Show flow map", spline.debugFlowmap);
spline.debugPoints = EditorGUILayout.Toggle("Show points", spline.debugPoints);
spline.debugPointsConnect = EditorGUILayout.Toggle("Show points connect", spline.debugPointsConnect);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUILayout.Space();
}
else if (spline.toolbarInt == 1)
{
PointsUI();
}
else if (spline.toolbarInt == 2)
{
DrawVertexColorsUI();
}
else if (spline.toolbarInt == 3)
{
DrawFlowColorsUI();
}
else if (spline.toolbarInt == 4)
{
EditorGUILayout.HelpBox("\nSet 1 point and R.A.M will show potential river direction.\n", MessageType.Info);
GUILayout.Label("River simulation:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
spline.simulatedRiverLength = EditorGUILayout.FloatField("Simulation length", spline.simulatedRiverLength);
if (spline.simulatedRiverLength < 1)
spline.simulatedRiverLength = 1;
spline.simulatedRiverPoints = EditorGUILayout.IntSlider("Simulation points interval", spline.simulatedRiverPoints, 1, 100);
spline.simulatedMinStepSize = EditorGUILayout.Slider("Simulation sampling interval", spline.simulatedMinStepSize, 0.5f, 5);
spline.simulatedNoUp = EditorGUILayout.Toggle("Simulation block uphill", spline.simulatedNoUp);
spline.simulatedBreakOnUp = EditorGUILayout.Toggle("Simulation break on uphill", spline.simulatedBreakOnUp);
spline.noiseWidth = EditorGUILayout.Toggle("Add width noise", spline.noiseWidth);
if (spline.noiseWidth)
{
EditorGUI.indentLevel++;
spline.noiseMultiplierWidth = EditorGUILayout.FloatField("Noise Multiplier Width", spline.noiseMultiplierWidth);
spline.noiseSizeWidth = EditorGUILayout.FloatField("Noise Scale Width", spline.noiseSizeWidth);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
if (GUILayout.Button("Show simulated River"))
{
spline.SimulateRiver(false);
}
if (GUILayout.Button("Generate Simulated River"))
{
Undo.RecordObject(spline, "Spline changed");
spline.SimulateRiver();
}
if (GUILayout.Button("Remove points except first"))
{
spline.RemovePoints(0);
}
EditorGUI.indentLevel--;
}
else if (spline.toolbarInt == 5)
{
Terrain terrain = Terrain.activeTerrain;
if (terrain != null && terrain.terrainData != null && terrain.terrainData.terrainLayers != null)
{
RiverChannel();
}
else
EditorGUILayout.HelpBox("No terrain on scene.", MessageType.Warning);
}
else if (spline.toolbarInt == 6)
{
FilesManager();
}
else if (spline.toolbarInt == 7)
{
Tips();
}
#if VEGETATION_STUDIO
if (spline.toolbarInt == 10)
{
EditorGUILayout.Space();
GUILayout.Label("Vegetation Studio: ", EditorStyles.boldLabel);
spline.vegetationMaskPerimeter = EditorGUILayout.FloatField("Vegetation Mask Perimeter", spline.vegetationMaskPerimeter);
if (spline.vegetationMaskArea == null && GUILayout.Button("Add Vegetation Mask Area"))
{
spline.vegetationMaskArea = spline.gameObject.AddComponent<VegetationMaskArea>();
RegenerateVegetationMask();
}
if (spline.vegetationMaskArea != null && GUILayout.Button("Calculate hull outline"))
{
RegenerateVegetationMask();
}
}
#endif
#if VEGETATION_STUDIO_PRO
if (spline.toolbarInt == 10)
{
EditorGUILayout.Space();
GUILayout.Label("Vegetation Studio Pro: ", EditorStyles.boldLabel);
spline.vegetationMaskSize = EditorGUILayout.FloatField("Vegetation Mask Size", spline.vegetationMaskSize);
spline.vegetationBlendDistance = EditorGUILayout.FloatField("Vegetation Blend Distance", spline.vegetationBlendDistance);
spline.biomMaskResolution = EditorGUILayout.Slider("Mask Resolution", spline.biomMaskResolution, 0.1f, 1);
if (spline.biomeMaskArea != null)
spline.refreshMask = EditorGUILayout.Toggle("Auto Refresh Biome Mask", spline.refreshMask);
if (GUILayout.Button("Add Vegetation Biome Mask Area"))
{
spline.GenerateSpline();
if (spline.biomeMaskArea == null)
{
spline.biomeMaskArea = spline.GetComponentInChildren<BiomeMaskArea>();
if (spline.biomeMaskArea == null)
{
GameObject maskObject = new GameObject("MyMask");
maskObject.transform.SetParent(spline.transform);
spline.biomeMaskArea = maskObject.AddComponent<BiomeMaskArea>();
spline.biomeMaskArea.BiomeType = BiomeType.River;
}
}
if (spline.biomeMaskArea == null)
return;
RegeneratBiomeMask(false);
}
}
#endif
//if (spline.toolbarInt == 6)
//{
// DebugOptions();
//}
if (EditorGUI.EndChangeCheck())
{
if (spline != null)
{
Undo.RecordObject(spline, "Spline changed");
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
EditorGUILayout.Space();
if (spline.beginningSpline)
{
if (!spline.beginningSpline.endingChildSplines.Contains(spline))
{
spline.beginningSpline.endingChildSplines.Add(spline);
}
}
if (spline.endingSpline)
{
if (!spline.endingSpline.beginnigChildSplines.Contains(spline))
{
spline.endingSpline.beginnigChildSplines.Add(spline);
}
}
}
#if VEGETATION_STUDIO
private void RegenerateVegetationMask()
{
spline.vegetationMaskArea.AdditionalGrassPerimiterMax = spline.vegetationMaskPerimeter;
spline.vegetationMaskArea.AdditionalLargeObjectPerimiterMax = spline.vegetationMaskPerimeter;
spline.vegetationMaskArea.AdditionalObjectPerimiterMax = spline.vegetationMaskPerimeter;
spline.vegetationMaskArea.AdditionalPlantPerimiterMax = spline.vegetationMaskPerimeter;
spline.vegetationMaskArea.AdditionalTreePerimiterMax = spline.vegetationMaskPerimeter;
spline.vegetationMaskArea.GenerateHullNodes(spline.vegetationMaskArea.ReductionTolerance);
spline.GenerateSpline();
List<Vector3> worldspacePointList = new List<Vector3>();
for (int i = 0; i < spline.pointsUp.Count; i += 5)
{
Vector3 position = spline.transform.TransformPoint(spline.pointsUp[i]) + (spline.transform.TransformPoint(spline.pointsUp[i]) - spline.transform.TransformPoint(spline.pointsDown[i])).normalized * spline.vegetationMaskPerimeter;
worldspacePointList.Add(position);
}
for (int i = 0; i < spline.pointsDown.Count; i += 5)
{
int ind = spline.pointsDown.Count - i - 1;
Vector3 position = spline.transform.TransformPoint(spline.pointsDown[ind]) + (spline.transform.TransformPoint(spline.pointsDown[ind]) - spline.transform.TransformPoint(spline.pointsUp[ind])).normalized * spline.vegetationMaskPerimeter;
worldspacePointList.Add(position);
}
spline.vegetationMaskArea.ClearNodes();
for (var i = 0; i <= worldspacePointList.Count - 1; i++)
{
spline.vegetationMaskArea.AddNodeToEnd(worldspacePointList[i]);
}
spline.vegetationMaskArea.UpdateVegetationMask();
}
#endif
#if VEGETATION_STUDIO_PRO
void RegeneratBiomeMask(bool checkAuto = true)
{
if (checkAuto && !spline.refreshMask)
return;
if (spline.biomeMaskArea == null)
return;
List<bool> disableEdges = new List<bool>();
List<Vector3> worldspacePointList = new List<Vector3>();
for (int i = 0; i < spline.pointsUp.Count; i += (int)(1 / (float)spline.biomMaskResolution))
{
Vector3 position = spline.transform.TransformPoint(spline.pointsUp[i]) + (spline.transform.TransformPoint(spline.pointsUp[i]) - spline.transform.TransformPoint(spline.pointsDown[i])).normalized * spline.vegetationMaskSize;
worldspacePointList.Add(position);
if (i == 0 || (i + (int)(1 / (float)spline.biomMaskResolution)) >= spline.pointsUp.Count)
{
disableEdges.Add(true);
}
else
{
disableEdges.Add(false);
}
}
for (int i = 0; i < spline.pointsDown.Count; i += (int)(1 / (float)spline.biomMaskResolution))
{
int ind = spline.pointsDown.Count - i - 1;
Vector3 position = spline.transform.TransformPoint(spline.pointsDown[ind]) + (spline.transform.TransformPoint(spline.pointsDown[ind]) - spline.transform.TransformPoint(spline.pointsUp[ind])).normalized * spline.vegetationMaskSize;
worldspacePointList.Add(position);
if (i == 0 || (i + (int)(1 / (float)spline.biomMaskResolution)) >= spline.pointsDown.Count)
{
disableEdges.Add(true);
}
else
{
disableEdges.Add(false);
}
}
spline.biomeMaskArea.ClearNodes();
spline.biomeMaskArea.AddNodesToEnd(worldspacePointList.ToArray(), disableEdges.ToArray());
//these have default values but you can set them if you want a different default setting
spline.biomeMaskArea.BlendDistance = spline.vegetationBlendDistance;
spline.biomeMaskArea.NoiseScale = 5;
spline.biomeMaskArea.UseNoise = true;
if (spline.currentProfile != null)
{
spline.biomeMaskArea.BiomeType = (BiomeType)spline.currentProfile.biomeType;
}
else
spline.biomeMaskArea.BiomeType = BiomeType.River;
//These 3 curves holds the blend curves for vegetation and textures. they have default values;
//biomeMaskArea.BlendCurve;
//biomeMaskArea.InverseBlendCurve;
//biomeMaskArea.TextureBlendCurve;
spline.biomeMaskArea.UpdateBiomeMask();
}
#endif
void RiverChannel()
{
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
GUILayout.Label("Terrain carve:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
spline.terrainCarve = EditorGUILayout.CurveField("Terrain carve", spline.terrainCarve);
spline.terrainSmoothMultiplier = EditorGUILayout.Slider("Smooth", spline.terrainSmoothMultiplier, 0, 20);
spline.distSmooth = EditorGUILayout.FloatField("Smooth distance", spline.distSmooth);
spline.maskCarve = LayerMaskField("Layers", spline.maskCarve, true);
spline.noiseCarve = EditorGUILayout.Toggle("Add noise", spline.noiseCarve);
EditorGUILayout.Space();
if (spline.noiseCarve)
{
EditorGUI.indentLevel++;
spline.noiseMultiplierInside = EditorGUILayout.FloatField("Noise Multiplier Inside", spline.noiseMultiplierInside);
spline.noiseMultiplierOutside = EditorGUILayout.FloatField("Noise Multiplier Outside", spline.noiseMultiplierOutside);
spline.noiseSizeX = EditorGUILayout.FloatField("Noise scale X", spline.noiseSizeX);
spline.noiseSizeZ = EditorGUILayout.FloatField("Noise scale Z", spline.noiseSizeZ);
EditorGUI.indentLevel--;
}
//spline.distSmoothStart = EditorGUILayout.FloatField("Smooth start distance", spline.distSmoothStart);
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(spline, "River terrain changed");
if (terrainShapeShow)
spline.ShowTerrainCarve();
}
if (!terrainShapeShow && GUILayout.Button("Show terrain shape"))
{
spline.ShowTerrainCarve();
terrainShapeShow = true;
}
if (terrainShapeShow && GUILayout.Button("Hide terrain shape"))
{
if (spline.meshGO != null)
DestroyImmediate(spline.meshGO);
terrainShapeShow = false;
}
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
spline.overrideRiverRender = EditorGUILayout.Toggle("Debug Override river render", spline.overrideRiverRender);
EditorGUI.indentLevel--;
if (GUILayout.Button("Carve terrain"))
{
spline.ShowTerrainCarve();
spline.TerrainCarve();
terrainShapeShow = false;
}
EditorGUILayout.Space();
GUILayout.Label("Terrain paint:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
spline.terrainPaintCarve = EditorGUILayout.CurveField("Terrain paint", spline.terrainPaintCarve);
Terrain terrain = Terrain.activeTerrain;
//Debug.Log("terrain " + terrain.name);
int splatNumber = terrain.terrainData.terrainLayers.Length;
//Debug.Log("splatNumber "+ splatNumber);
string[] options = new string[splatNumber];
for (int i = 0; i < splatNumber; i++)
{
options[i] = i + " - ";
//Debug.Log("diffuseTexture is null " + (terrain.terrainData.terrainLayers[i].diffuseTexture == null));
if (terrain.terrainData.terrainLayers[i] != null && terrain.terrainData.terrainLayers[i].diffuseTexture != null)
{
//Debug.Log(terrain.terrainData.terrainLayers[i].diffuseTexture.name);
options[i] += terrain.terrainData.terrainLayers[i].diffuseTexture.name;
}
}
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Splat id:");
spline.currentSplatMap = EditorGUILayout.Popup(spline.currentSplatMap, options);
EditorGUILayout.EndHorizontal();
spline.noisePaint = EditorGUILayout.Toggle("Add noise", spline.noisePaint);
if (spline.noisePaint)
{
EditorGUI.indentLevel++;
spline.noiseMultiplierInsidePaint = EditorGUILayout.FloatField("Noise Multiplier Inside", spline.noiseMultiplierInsidePaint);
spline.noiseMultiplierOutsidePaint = EditorGUILayout.FloatField("Noise Multiplier Outside", spline.noiseMultiplierOutsidePaint);
spline.noiseSizeXPaint = EditorGUILayout.FloatField("Noise scale X", spline.noiseSizeXPaint);
spline.noiseSizeZPaint = EditorGUILayout.FloatField("Noise scale Z", spline.noiseSizeZPaint);
EditorGUI.indentLevel--;
}
spline.mixTwoSplatMaps = EditorGUILayout.Toggle("Mix two splat maps", spline.mixTwoSplatMaps);
if (spline.mixTwoSplatMaps)
{
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Second splat id:");
spline.secondSplatMap = EditorGUILayout.Popup(spline.secondSplatMap, options);
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
}
spline.addCliffSplatMap = EditorGUILayout.Toggle("Add cliff splatmap", spline.addCliffSplatMap);
if (spline.addCliffSplatMap)
{
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Cliff splat id:");
spline.cliffSplatMap = EditorGUILayout.Popup(spline.cliffSplatMap, options);
EditorGUILayout.EndHorizontal();
spline.cliffAngle = EditorGUILayout.FloatField("Cliff angle", spline.cliffAngle);
spline.cliffBlend = EditorGUILayout.FloatField("Cliff blend", spline.cliffBlend);
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
GUILayout.Label(" Cliff outside splat id:");
spline.cliffSplatMapOutside = EditorGUILayout.Popup(spline.cliffSplatMapOutside, options);
EditorGUILayout.EndHorizontal();
spline.cliffAngleOutside = EditorGUILayout.FloatField("Cliff outside angle", spline.cliffAngleOutside);
spline.cliffBlendOutside = EditorGUILayout.FloatField("Cliff outside blend", spline.cliffBlendOutside);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(spline, "River terrain changed");
if (spline.meshGO != null)
{
if (spline.overrideRiverRender)
spline.meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 5000;
else
spline.meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 2980;
}
}
EditorGUI.indentLevel--;
//Debug.Log(splatNumber);
//Debug.Log(spline.currentSplatMap);
if (splatNumber > 0 && splatNumber > spline.currentSplatMap)
{
if (GUILayout.Button("Paint Terrain"))
{
spline.ShowTerrainCarve();
spline.TerrainPaintMeshBased();
terrainShapeShow = false;
}
}
else
EditorGUILayout.HelpBox("No splat id selected to paint", MessageType.Error);
EditorGUILayout.Space();
GUILayout.Label("Terrain clear foliage:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
spline.distanceClearFoliage = EditorGUILayout.FloatField("Remove Details Distance", spline.distanceClearFoliage);
if (GUILayout.Button("Remove Details Foliage"))
{
spline.ShowTerrainCarve(spline.distanceClearFoliage);
spline.TerrainClearFoliage();
terrainShapeShow = false;
}
spline.distanceClearFoliageTrees = EditorGUILayout.FloatField("Remove Trees Distance", spline.distanceClearFoliageTrees);
if (GUILayout.Button("Remove Trees"))
{
spline.ShowTerrainCarve(spline.distanceClearFoliageTrees);
spline.TerrainClearFoliage(false);
terrainShapeShow = false;
}
EditorGUI.indentLevel--;
}
public static float DistancePointLine(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{
return Vector3.Distance(ProjectPointLine(point, lineStart, lineEnd), point);
}
public static Vector3 ProjectPointLine(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{
Vector3 rhs = point - lineStart;
Vector3 vector2 = lineEnd - lineStart;
float magnitude = vector2.magnitude;
Vector3 lhs = vector2;
if (magnitude > 1E-06f)
{
lhs = (Vector3)(lhs / magnitude);
}
float num2 = Mathf.Clamp(Vector3.Dot(lhs, rhs), 0f, magnitude);
return (lineStart + ((Vector3)(lhs * num2)));
}
void DebugOptions()
{
EditorGUILayout.LabelField("splitParameter", spline.uvBeginning.ToString());
EditorGUILayout.LabelField("beginningMinWidth", spline.beginningMinWidth.ToString());
EditorGUILayout.LabelField("beginningMaxWidth", spline.beginningMaxWidth.ToString());
EditorGUILayout.LabelField("minMaxWidth", spline.minMaxWidth.ToString());
EditorGUILayout.LabelField("uvBeginning", spline.uvBeginning.ToString());
EditorGUILayout.LabelField("uvWidth", spline.uvWidth.ToString());
if (GUILayout.Button(new GUIContent("Regenerate spline", "Racalculates whole mesh")))
{
spline.GenerateSpline();
}
}
void AddPointAtEnd()
{
if (GUILayout.Button("Add point at end"))
{
int i = spline.controlPoints.Count - 1;
Vector4 position = Vector3.zero;
position.w = spline.width;
if (i < spline.controlPoints.Count - 1 && spline.controlPoints.Count > i + 1)
{
position = spline.controlPoints[i];
Vector4 positionSecond = spline.controlPoints[i + 1];
if (Vector3.Distance((Vector3)positionSecond, (Vector3)position) > 0)
position = (position + positionSecond) * 0.5f;
else
position.x += 1;
}
else if (spline.controlPoints.Count > 1 && i == spline.controlPoints.Count - 1)
{
position = spline.controlPoints[i];
Vector4 positionSecond = spline.controlPoints[i - 1];
if (Vector3.Distance((Vector3)positionSecond, (Vector3)position) > 0)
position = position + (position - positionSecond);
else
position.x += 1;
}
else if (spline.controlPoints.Count > 0)
{
position = spline.controlPoints[i];
position.x += 1;
}
spline.controlPointsRotations.Add(Quaternion.identity);
spline.controlPoints.Add(position);
spline.controlPointsSnap.Add(0);
spline.controlPointsMeshCurves.Add(new AnimationCurve(new Keyframe[] {
new Keyframe (0, 0),
new Keyframe (1, 0)
}));
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
void SplitRiver(int pointID)
{
if (pointID < 0 || pointID >= spline.controlPoints.Count)
return;
Undo.RecordObject(spline, "Split river");
List<Vector4> ramFirstPoints = new List<Vector4>();
List<Vector4> ramSecondPoints = new List<Vector4>();
for (int i = 0; i < spline.controlPoints.Count; i++)
{
if (i <= pointID)
{
ramFirstPoints.Add(spline.controlPoints[i]);
}
if (i >= pointID)
{
ramSecondPoints.Add(spline.controlPoints[i]);
}
}
MeshRenderer ren = spline.GetComponent<MeshRenderer>();
RamSpline ramFirst = RamSpline.CreateSpline(ren.sharedMaterial, ramFirstPoints, spline.name + "_1");
RamSpline ramSecond = RamSpline.CreateSpline(ren.sharedMaterial, ramSecondPoints, spline.name + "_2");
if (spline.currentProfile != null)
{
ramFirst.currentProfile = spline.currentProfile;
ramFirst.oldProfile = ramFirst.currentProfile;
ramSecond.currentProfile = spline.currentProfile;
ramSecond.oldProfile = ramSecond.currentProfile;
}
//
ramFirst.meshCurve = new AnimationCurve(spline.meshCurve.keys);
ramFirst.flowFlat = new AnimationCurve(spline.flowFlat.keys);
ramFirst.flowWaterfall = new AnimationCurve(spline.flowWaterfall.keys);
ramFirst.terrainCarve = new AnimationCurve(spline.terrainCarve.keys);
ramFirst.terrainPaintCarve = new AnimationCurve(spline.terrainPaintCarve.keys);
for (int i = 0; i < ramFirst.controlPointsMeshCurves.Count; i++)
{
ramFirst.controlPointsMeshCurves[i] = new AnimationCurve(spline.meshCurve.keys);
}
ramFirst.minVal = spline.minVal;
ramFirst.maxVal = spline.maxVal;
ramFirst.traingleDensity = spline.traingleDensity;
ramFirst.vertsInShape = spline.vertsInShape;
ramFirst.uvScale = spline.uvScale;
ramFirst.uvRotation = spline.uvRotation;
ramFirst.noiseflowMap = spline.noiseflowMap;
ramFirst.noiseMultiplierflowMap = spline.noiseMultiplierflowMap;
ramFirst.noiseSizeXflowMap = spline.noiseSizeXflowMap;
ramFirst.noiseSizeZflowMap = spline.noiseSizeZflowMap;
ramFirst.floatSpeed = spline.floatSpeed;
ramFirst.distSmooth = spline.distSmooth;
ramFirst.distSmoothStart = spline.distSmoothStart;
ramFirst.noiseCarve = spline.noiseCarve;
ramFirst.noiseMultiplierInside = spline.noiseMultiplierInside;
ramFirst.noiseMultiplierOutside = spline.noiseMultiplierOutside;
ramFirst.noiseSizeX = spline.noiseSizeX;
ramFirst.noiseSizeZ = spline.noiseSizeZ;
ramFirst.terrainSmoothMultiplier = spline.terrainSmoothMultiplier;
ramFirst.currentSplatMap = spline.currentSplatMap;
ramFirst.mixTwoSplatMaps = spline.mixTwoSplatMaps;
ramFirst.secondSplatMap = spline.secondSplatMap;
ramFirst.addCliffSplatMap = spline.addCliffSplatMap;
ramFirst.cliffSplatMap = spline.cliffSplatMap;
ramFirst.cliffAngle = spline.cliffAngle;
ramFirst.cliffBlend = spline.cliffBlend;
ramFirst.cliffSplatMapOutside = spline.cliffSplatMapOutside;
ramFirst.cliffAngleOutside = spline.cliffAngleOutside;
ramFirst.cliffBlendOutside = spline.cliffBlendOutside;
ramFirst.distanceClearFoliage = spline.distanceClearFoliage;
ramFirst.distanceClearFoliageTrees = spline.distanceClearFoliageTrees;
ramFirst.noisePaint = spline.noisePaint;
ramFirst.noiseMultiplierInsidePaint = spline.noiseMultiplierInsidePaint;
ramFirst.noiseMultiplierOutsidePaint = spline.noiseMultiplierOutsidePaint;
ramFirst.noiseSizeXPaint = spline.noiseSizeXPaint;
ramFirst.noiseSizeZPaint = spline.noiseSizeZPaint;
ramFirst.simulatedRiverLength = spline.simulatedRiverLength;
ramFirst.simulatedRiverPoints = spline.simulatedRiverPoints;
ramFirst.simulatedMinStepSize = spline.simulatedMinStepSize;
ramFirst.simulatedNoUp = spline.simulatedNoUp;
ramFirst.simulatedBreakOnUp = spline.simulatedBreakOnUp;
ramFirst.noiseWidth = spline.noiseWidth;
ramFirst.noiseMultiplierWidth = spline.noiseMultiplierWidth;
ramFirst.noiseSizeWidth = spline.noiseSizeWidth;
ramFirst.receiveShadows = spline.receiveShadows;
ramFirst.shadowCastingMode = spline.shadowCastingMode;
ramSecond.meshCurve = new AnimationCurve(spline.meshCurve.keys);
ramSecond.flowFlat = new AnimationCurve(spline.flowFlat.keys);
ramSecond.flowWaterfall = new AnimationCurve(spline.flowWaterfall.keys);
ramSecond.terrainCarve = new AnimationCurve(spline.terrainCarve.keys);
ramSecond.terrainPaintCarve = new AnimationCurve(spline.terrainPaintCarve.keys);
for (int i = 0; i < ramSecond.controlPointsMeshCurves.Count; i++)
{
ramSecond.controlPointsMeshCurves[i] = new AnimationCurve(spline.meshCurve.keys);
}
ramSecond.minVal = spline.minVal;
ramSecond.maxVal = spline.maxVal;
ramSecond.traingleDensity = spline.traingleDensity;
ramSecond.vertsInShape = spline.vertsInShape;
ramSecond.uvScale = spline.uvScale;
ramSecond.uvRotation = spline.uvRotation;
ramSecond.noiseflowMap = spline.noiseflowMap;
ramSecond.noiseMultiplierflowMap = spline.noiseMultiplierflowMap;
ramSecond.noiseSizeXflowMap = spline.noiseSizeXflowMap;
ramSecond.noiseSizeZflowMap = spline.noiseSizeZflowMap;
ramSecond.floatSpeed = spline.floatSpeed;
ramSecond.distSmooth = spline.distSmooth;
ramSecond.distSmoothStart = spline.distSmoothStart;
ramSecond.noiseCarve = spline.noiseCarve;
ramSecond.noiseMultiplierInside = spline.noiseMultiplierInside;
ramSecond.noiseMultiplierOutside = spline.noiseMultiplierOutside;
ramSecond.noiseSizeX = spline.noiseSizeX;
ramSecond.noiseSizeZ = spline.noiseSizeZ;
ramSecond.terrainSmoothMultiplier = spline.terrainSmoothMultiplier;
ramSecond.currentSplatMap = spline.currentSplatMap;
ramSecond.mixTwoSplatMaps = spline.mixTwoSplatMaps;
ramSecond.secondSplatMap = spline.secondSplatMap;
ramSecond.addCliffSplatMap = spline.addCliffSplatMap;
ramSecond.cliffSplatMap = spline.cliffSplatMap;
ramSecond.cliffAngle = spline.cliffAngle;
ramSecond.cliffBlend = spline.cliffBlend;
ramSecond.cliffSplatMapOutside = spline.cliffSplatMapOutside;
ramSecond.cliffAngleOutside = spline.cliffAngleOutside;
ramSecond.cliffBlendOutside = spline.cliffBlendOutside;
ramSecond.distanceClearFoliage = spline.distanceClearFoliage;
ramSecond.distanceClearFoliageTrees = spline.distanceClearFoliageTrees;
ramSecond.noisePaint = spline.noisePaint;
ramSecond.noiseMultiplierInsidePaint = spline.noiseMultiplierInsidePaint;
ramSecond.noiseMultiplierOutsidePaint = spline.noiseMultiplierOutsidePaint;
ramSecond.noiseSizeXPaint = spline.noiseSizeXPaint;
ramSecond.noiseSizeZPaint = spline.noiseSizeZPaint;
ramSecond.simulatedRiverLength = spline.simulatedRiverLength;
ramSecond.simulatedRiverPoints = spline.simulatedRiverPoints;
ramSecond.simulatedMinStepSize = spline.simulatedMinStepSize;
ramSecond.simulatedNoUp = spline.simulatedNoUp;
ramSecond.simulatedBreakOnUp = spline.simulatedBreakOnUp;
ramSecond.noiseWidth = spline.noiseWidth;
ramSecond.noiseMultiplierWidth = spline.noiseMultiplierWidth;
ramSecond.noiseSizeWidth = spline.noiseSizeWidth;
ramSecond.receiveShadows = spline.receiveShadows;
ramSecond.shadowCastingMode = spline.shadowCastingMode;
//
ramFirst.endingSpline = ramSecond;
ramFirst.endingMinWidth = 0;
ramFirst.endingMaxWidth = 1;
ramSecond.GenerateSpline();
ramFirst.GenerateSpline();
ramFirst.transform.position = spline.transform.position;
ramSecond.transform.position = spline.transform.position;
Undo.DestroyObjectImmediate(spline.gameObject);
}
void MeshSettings()
{
GUILayout.Label("Mesh settings:", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
spline.currentProfile = (SplineProfile)EditorGUILayout.ObjectField("Spline profile", spline.currentProfile, typeof(SplineProfile), false);
if (GUILayout.Button("Create profile from settings"))
{
SplineProfile asset = ScriptableObject.CreateInstance<SplineProfile>();
//asset.meshCurve = spline.meshCurve;
asset.meshCurve = new AnimationCurve(spline.meshCurve.keys);
asset.flowFlat = new AnimationCurve(spline.flowFlat.keys);
asset.flowWaterfall = new AnimationCurve(spline.flowWaterfall.keys);
asset.terrainCarve = new AnimationCurve(spline.terrainCarve.keys);
asset.terrainPaintCarve = new AnimationCurve(spline.terrainPaintCarve.keys);
MeshRenderer ren = spline.GetComponent<MeshRenderer>();
asset.splineMaterial = ren.sharedMaterial;
asset.minVal = spline.minVal;
asset.maxVal = spline.maxVal;
asset.traingleDensity = spline.traingleDensity;
asset.vertsInShape = spline.vertsInShape;
asset.uvScale = spline.uvScale;
asset.uvRotation = spline.uvRotation;
//asset.flowFlat = spline.flowFlat;
//asset.flowWaterfall = spline.flowWaterfall;
asset.noiseflowMap = spline.noiseflowMap;
asset.noiseMultiplierflowMap = spline.noiseMultiplierflowMap;
asset.noiseSizeXflowMap = spline.noiseSizeXflowMap;
asset.noiseSizeZflowMap = spline.noiseSizeZflowMap;
asset.floatSpeed = spline.floatSpeed;
// asset.terrainCarve = spline.terrainCarve;
asset.distSmooth = spline.distSmooth;
asset.distSmoothStart = spline.distSmoothStart;
// asset.terrainPaintCarve = spline.terrainPaintCarve;
asset.noiseCarve = spline.noiseCarve;
asset.noiseMultiplierInside = spline.noiseMultiplierInside;
asset.noiseMultiplierOutside = spline.noiseMultiplierOutside;
asset.noiseSizeX = spline.noiseSizeX;
asset.noiseSizeZ = spline.noiseSizeZ;
asset.terrainSmoothMultiplier = spline.terrainSmoothMultiplier;
asset.currentSplatMap = spline.currentSplatMap;
asset.mixTwoSplatMaps = spline.mixTwoSplatMaps;
asset.secondSplatMap = spline.secondSplatMap;
asset.addCliffSplatMap = spline.addCliffSplatMap;
asset.cliffSplatMap = spline.cliffSplatMap;
asset.cliffAngle = spline.cliffAngle;
asset.cliffBlend = spline.cliffBlend;
asset.cliffSplatMapOutside = spline.cliffSplatMapOutside;
asset.cliffAngleOutside = spline.cliffAngleOutside;
asset.cliffBlendOutside = spline.cliffBlendOutside;
asset.distanceClearFoliage = spline.distanceClearFoliage;
asset.distanceClearFoliageTrees = spline.distanceClearFoliageTrees;
asset.noisePaint = spline.noisePaint;
asset.noiseMultiplierInsidePaint = spline.noiseMultiplierInsidePaint;
asset.noiseMultiplierOutsidePaint = spline.noiseMultiplierOutsidePaint;
asset.noiseSizeXPaint = spline.noiseSizeXPaint;
asset.noiseSizeZPaint = spline.noiseSizeZPaint;
asset.simulatedRiverLength = spline.simulatedRiverLength;
asset.simulatedRiverPoints = spline.simulatedRiverPoints;
asset.simulatedMinStepSize = spline.simulatedMinStepSize;
asset.simulatedNoUp = spline.simulatedNoUp;
asset.simulatedBreakOnUp = spline.simulatedBreakOnUp;
asset.noiseWidth = spline.noiseWidth;
asset.noiseMultiplierWidth = spline.noiseMultiplierWidth;
asset.noiseSizeWidth = spline.noiseSizeWidth;
asset.receiveShadows = spline.receiveShadows;
asset.shadowCastingMode = spline.shadowCastingMode;
string path = EditorUtility.SaveFilePanelInProject("Save new spline profile", spline.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();
spline.currentProfile = asset;
}
}
if (spline.currentProfile != null && GUILayout.Button("Save profile from settings"))
{
//spline.currentProfile.meshCurve = spline.meshCurve;
MeshRenderer ren = spline.GetComponent<MeshRenderer>();
spline.currentProfile.splineMaterial = ren.sharedMaterial;
spline.currentProfile.minVal = spline.minVal;
spline.currentProfile.maxVal = spline.maxVal;
spline.currentProfile.meshCurve = new AnimationCurve(spline.meshCurve.keys);
spline.currentProfile.flowFlat = new AnimationCurve(spline.flowFlat.keys);
spline.currentProfile.flowWaterfall = new AnimationCurve(spline.flowWaterfall.keys);
spline.currentProfile.terrainCarve = new AnimationCurve(spline.terrainCarve.keys);
spline.currentProfile.terrainPaintCarve = new AnimationCurve(spline.terrainPaintCarve.keys);
spline.currentProfile.traingleDensity = spline.traingleDensity;
spline.currentProfile.vertsInShape = spline.vertsInShape;
spline.currentProfile.uvScale = spline.uvScale;
spline.currentProfile.uvRotation = spline.uvRotation;
// spline.currentProfile.flowFlat = spline.flowFlat;
//spline.currentProfile.flowWaterfall = spline.flowWaterfall;
spline.currentProfile.noiseflowMap = spline.noiseflowMap;
spline.currentProfile.noiseMultiplierflowMap = spline.noiseMultiplierflowMap;
spline.currentProfile.noiseSizeXflowMap = spline.noiseSizeXflowMap;
spline.currentProfile.noiseSizeZflowMap = spline.noiseSizeZflowMap;
spline.currentProfile.floatSpeed = spline.floatSpeed;
//spline.currentProfile.terrainCarve = spline.terrainCarve;
spline.currentProfile.distSmooth = spline.distSmooth;
spline.currentProfile.distSmoothStart = spline.distSmoothStart;
spline.currentProfile.maskCarve = spline.maskCarve;
//spline.currentProfile.terrainPaintCarve = spline.terrainPaintCarve;
spline.currentProfile.noiseCarve = spline.noiseCarve;
spline.currentProfile.noiseMultiplierInside = spline.noiseMultiplierInside;
spline.currentProfile.noiseMultiplierOutside = spline.noiseMultiplierOutside;
spline.currentProfile.noiseSizeX = spline.noiseSizeX;
spline.currentProfile.noiseSizeZ = spline.noiseSizeZ;
spline.currentProfile.terrainSmoothMultiplier = spline.terrainSmoothMultiplier;
spline.currentProfile.currentSplatMap = spline.currentSplatMap;
spline.currentProfile.mixTwoSplatMaps = spline.mixTwoSplatMaps;
spline.currentProfile.secondSplatMap = spline.secondSplatMap;
spline.currentProfile.addCliffSplatMap = spline.addCliffSplatMap;
spline.currentProfile.cliffSplatMap = spline.cliffSplatMap;
spline.currentProfile.cliffAngle = spline.cliffAngle;
spline.currentProfile.cliffBlend = spline.cliffBlend;
spline.currentProfile.cliffSplatMapOutside = spline.cliffSplatMapOutside;
spline.currentProfile.cliffAngleOutside = spline.cliffAngleOutside;
spline.currentProfile.cliffBlendOutside = spline.cliffBlendOutside;
spline.currentProfile.distanceClearFoliage = spline.distanceClearFoliage;
spline.currentProfile.distanceClearFoliageTrees = spline.distanceClearFoliageTrees;
spline.currentProfile.noisePaint = spline.noisePaint;
spline.currentProfile.noiseMultiplierInsidePaint = spline.noiseMultiplierInsidePaint;
spline.currentProfile.noiseMultiplierOutsidePaint = spline.noiseMultiplierOutsidePaint;
spline.currentProfile.noiseSizeXPaint = spline.noiseSizeXPaint;
spline.currentProfile.noiseSizeZPaint = spline.noiseSizeZPaint;
spline.currentProfile.simulatedRiverLength = spline.simulatedRiverLength;
spline.currentProfile.simulatedRiverPoints = spline.simulatedRiverPoints;
spline.currentProfile.simulatedMinStepSize = spline.simulatedMinStepSize;
spline.currentProfile.simulatedNoUp = spline.simulatedNoUp;
spline.currentProfile.simulatedBreakOnUp = spline.simulatedBreakOnUp;
spline.currentProfile.noiseWidth = spline.noiseWidth;
spline.currentProfile.noiseMultiplierWidth = spline.noiseMultiplierWidth;
spline.currentProfile.noiseSizeWidth = spline.noiseSizeWidth;
spline.currentProfile.receiveShadows = spline.receiveShadows;
spline.currentProfile.shadowCastingMode = spline.shadowCastingMode;
AssetDatabase.SaveAssets();
}
if (spline.currentProfile != null && spline.currentProfile != spline.oldProfile)
{
ResetToProfile();
EditorUtility.SetDirty(spline);
}
bool profileChanged = CheckProfileChange();
if (spline.currentProfile != null && GUILayout.Button("Reset to profile" + (profileChanged ? " (Profile data changed)" : "")))
{
ResetToProfile();
}
EditorGUILayout.Space();
string meshResolution = "Triangles density";
if (spline.meshfilter != null && spline.meshfilter.sharedMesh != null)
{
float tris = spline.meshfilter.sharedMesh.triangles.Length / 3;
meshResolution += " (" + tris + " tris)";
}
else if (spline.meshfilter != null && spline.meshfilter.sharedMesh == null)
{
spline.GenerateSpline();
}
EditorGUILayout.LabelField(meshResolution);
EditorGUI.indentLevel++;
spline.traingleDensity = 1 / (float)EditorGUILayout.IntSlider("U", (int)(1 / (float)spline.traingleDensity), 1, 100);
if (spline.beginningSpline == null && spline.endingSpline == null)
{
spline.vertsInShape = EditorGUILayout.IntSlider("V", spline.vertsInShape - 1, 1, 20) + 1;
}
else
{
GUI.enabled = false;
if (spline.beginningSpline != null)
{
spline.vertsInShape = (int)Mathf.Round((spline.beginningSpline.vertsInShape - 1) * (spline.beginningMaxWidth - spline.beginningMinWidth) + 1);
}
else if (spline.endingSpline != null)
spline.vertsInShape = (int)Mathf.Round((spline.endingSpline.vertsInShape - 1) * (spline.endingMaxWidth - spline.endingMinWidth) + 1);
EditorGUILayout.IntSlider("V", spline.vertsInShape - 1, 1, 20);
GUI.enabled = true;
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
{
spline.width = EditorGUILayout.FloatField("River width", spline.width);
if (GUILayout.Button("Change width for whole river"))
{
if (spline.width > 0)
{
for (int i = 0; i < spline.controlPoints.Count; i++)
{
Vector4 point = spline.controlPoints[i];
point.w = spline.width;
spline.controlPoints[i] = point;
}
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
}
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel++;
spline.noiseWidth = EditorGUILayout.Toggle("Add width noise", spline.noiseWidth);
if (spline.noiseWidth)
{
EditorGUI.indentLevel++;
spline.noiseMultiplierWidth = EditorGUILayout.FloatField("Noise Multiplier Width", spline.noiseMultiplierWidth);
spline.noiseSizeWidth = EditorGUILayout.FloatField("Noise scale Width", spline.noiseSizeWidth);
EditorGUI.indentLevel--;
if (GUILayout.Button("Add noise to width for whole river"))
{
Undo.RecordObject(spline, "Change widths");
spline.AddNoiseToWidths();
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
spline.meshCurve = EditorGUILayout.CurveField("Mesh curve", spline.meshCurve);
if (GUILayout.Button("Set all mesh curves"))
{
for (int i = 0; i < spline.controlPointsMeshCurves.Count; i++)
{
spline.controlPointsMeshCurves[i] = new AnimationCurve(spline.meshCurve.keys);
}
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Vertice distribution: " + spline.minVal.ToString() + " " + spline.maxVal.ToString());
EditorGUILayout.MinMaxSlider(ref spline.minVal, ref spline.maxVal, 0, 1);
//Debug.Log (spline.minVal + " " + spline.maxVal);
spline.minVal = (int)(spline.minVal * 100) * 0.01f;
spline.maxVal = (int)(spline.maxVal * 100) * 0.01f;
if (spline.minVal > 0.5f)
spline.minVal = 0.5f;
if (spline.minVal < 0.01f)
spline.minVal = 0.01f;
if (spline.maxVal < 0.5f)
spline.maxVal = 0.5f;
if (spline.maxVal > 0.99f)
spline.maxVal = 0.99f;
EditorGUILayout.Space();
if (GUILayout.Button("Snap/Unsnap mesh to terrain"))
{
spline.snapToTerrain = !spline.snapToTerrain;
for (int i = 0; i < spline.controlPointsSnap.Count; i++)
{
spline.controlPointsSnap[i] = spline.snapToTerrain == true ? 1 : 0;
}
}
///spline.snapMask = EditorGUILayout.MaskField ("Layers", spline.snapMask, InternalEditorUtility.layers);
spline.snapMask = LayerMaskField("Layers", spline.snapMask, true);
spline.normalFromRaycast = EditorGUILayout.Toggle("Take Normal from terrain", spline.normalFromRaycast);
EditorGUILayout.Space();
}
bool CheckProfileChange()
{
if (spline.currentProfile == null)
return false;
//if (ren.material != spline.currentProfile.splineMaterial)
// return true;
if (spline.minVal != spline.currentProfile.minVal)
return true;
if (spline.maxVal != spline.currentProfile.maxVal)
return true;
if (spline.traingleDensity != spline.currentProfile.traingleDensity)
return true;
if (spline.vertsInShape != spline.currentProfile.vertsInShape)
return true;
if (spline.uvScale != spline.currentProfile.uvScale)
return true;
if (spline.uvRotation != spline.currentProfile.uvRotation)
return true;
// if (spline.flowFlat != spline.currentProfile.flowFlat)
// return true;
// if (spline.flowWaterfall != spline.currentProfile.flowWaterfall)
// return true;
if (spline.noiseflowMap != spline.currentProfile.noiseflowMap)
return true;
if (spline.noiseMultiplierflowMap != spline.currentProfile.noiseMultiplierflowMap)
return true;
if (spline.noiseSizeXflowMap != spline.currentProfile.noiseSizeXflowMap)
return true;
if (spline.noiseSizeZflowMap != spline.currentProfile.noiseSizeZflowMap)
return true;
if (spline.floatSpeed != spline.currentProfile.floatSpeed)
return true;
// if (spline.terrainCarve != spline.currentProfile.terrainCarve)
// return true;
if (spline.distSmooth != spline.currentProfile.distSmooth)
return true;
if (spline.distSmoothStart != spline.currentProfile.distSmoothStart)
return true;
if (spline.maskCarve != spline.currentProfile.maskCarve)
return true;
// if (spline.terrainPaintCarve != spline.currentProfile.terrainPaintCarve)
// return true;
if (spline.currentProfile.noiseCarve != spline.noiseCarve)
return true;
if (spline.currentProfile.noiseMultiplierInside != spline.noiseMultiplierInside)
return true;
if (spline.currentProfile.noiseMultiplierOutside != spline.noiseMultiplierOutside)
return true;
if (spline.currentProfile.noiseSizeX != spline.noiseSizeX)
return true;
if (spline.currentProfile.noiseSizeZ != spline.noiseSizeZ)
return true;
if (spline.currentProfile.terrainSmoothMultiplier != spline.terrainSmoothMultiplier)
return true;
if (spline.currentProfile.currentSplatMap != spline.currentSplatMap)
return true;
if (spline.currentProfile.mixTwoSplatMaps != spline.mixTwoSplatMaps)
return true;
if (spline.currentProfile.secondSplatMap != spline.secondSplatMap)
return true;
if (spline.currentProfile.addCliffSplatMap != spline.addCliffSplatMap)
return true;
if (spline.currentProfile.cliffSplatMap != spline.cliffSplatMap)
return true;
if (spline.currentProfile.cliffAngle != spline.cliffAngle)
return true;
if (spline.currentProfile.cliffBlend != spline.cliffBlend)
return true;
if (spline.currentProfile.cliffSplatMapOutside != spline.cliffSplatMapOutside)
return true;
if (spline.currentProfile.cliffAngleOutside != spline.cliffAngleOutside)
return true;
if (spline.currentProfile.cliffBlendOutside != spline.cliffBlendOutside)
return true;
if (spline.currentProfile.distanceClearFoliage != spline.distanceClearFoliage)
return true;
if (spline.currentProfile.distanceClearFoliageTrees != spline.distanceClearFoliageTrees)
return true;
if (spline.currentProfile.noisePaint != spline.noisePaint)
return true;
if (spline.currentProfile.noiseMultiplierInsidePaint != spline.noiseMultiplierInsidePaint)
return true;
if (spline.currentProfile.noiseMultiplierOutsidePaint != spline.noiseMultiplierOutsidePaint)
return true;
if (spline.currentProfile.noiseSizeXPaint != spline.noiseSizeXPaint)
return true;
if (spline.currentProfile.noiseSizeZPaint != spline.noiseSizeZPaint)
return true;
if (spline.currentProfile.simulatedRiverLength != spline.simulatedRiverLength)
return true;
if (spline.currentProfile.simulatedRiverPoints != spline.simulatedRiverPoints)
return true;
if (spline.currentProfile.simulatedMinStepSize != spline.simulatedMinStepSize)
return true;
if (spline.currentProfile.simulatedNoUp != spline.simulatedNoUp)
return true;
if (spline.currentProfile.simulatedBreakOnUp != spline.simulatedBreakOnUp)
return true;
if (spline.currentProfile.noiseWidth != spline.noiseWidth)
return true;
if (spline.currentProfile.noiseMultiplierWidth != spline.noiseMultiplierWidth)
return true;
if (spline.currentProfile.noiseSizeWidth != spline.noiseSizeWidth)
return true;
if (spline.receiveShadows != spline.currentProfile.receiveShadows)
return true;
if (spline.shadowCastingMode != spline.currentProfile.shadowCastingMode)
return true;
return false;
}
public void ResetToProfile()
{
if (spline == null)
spline = (RamSpline)target;
//spline.meshCurve = spline.currentProfile.meshCurve;
spline.meshCurve = new AnimationCurve(spline.currentProfile.meshCurve.keys);
spline.flowFlat = new AnimationCurve(spline.currentProfile.flowFlat.keys);
spline.flowWaterfall = new AnimationCurve(spline.currentProfile.flowWaterfall.keys);
spline.terrainCarve = new AnimationCurve(spline.currentProfile.terrainCarve.keys);
spline.terrainPaintCarve = new AnimationCurve(spline.currentProfile.terrainPaintCarve.keys);
for (int i = 0; i < spline.controlPointsMeshCurves.Count; i++)
{
spline.controlPointsMeshCurves[i] = new AnimationCurve(spline.meshCurve.keys);
}
MeshRenderer ren = spline.GetComponent<MeshRenderer>();
ren.sharedMaterial = spline.currentProfile.splineMaterial;
spline.minVal = spline.currentProfile.minVal;
spline.maxVal = spline.currentProfile.maxVal;
spline.traingleDensity = spline.currentProfile.traingleDensity;
spline.vertsInShape = spline.currentProfile.vertsInShape;
spline.uvScale = spline.currentProfile.uvScale;
spline.uvRotation = spline.currentProfile.uvRotation;
//spline.flowFlat = spline.currentProfile.flowFlat;
//spline.flowWaterfall = spline.currentProfile.flowWaterfall;
spline.noiseflowMap = spline.currentProfile.noiseflowMap;
spline.noiseMultiplierflowMap = spline.currentProfile.noiseMultiplierflowMap;
spline.noiseSizeXflowMap = spline.currentProfile.noiseSizeXflowMap;
spline.noiseSizeZflowMap = spline.currentProfile.noiseSizeZflowMap;
spline.floatSpeed = spline.currentProfile.floatSpeed;
//spline.terrainCarve = spline.currentProfile.terrainCarve;
spline.distSmooth = spline.currentProfile.distSmooth;
spline.distSmoothStart = spline.currentProfile.distSmoothStart;
spline.maskCarve = spline.currentProfile.maskCarve;
//spline.terrainPaintCarve = spline.currentProfile.terrainPaintCarve;
spline.noiseCarve = spline.currentProfile.noiseCarve;
spline.noiseMultiplierInside = spline.currentProfile.noiseMultiplierInside;
spline.noiseMultiplierOutside = spline.currentProfile.noiseMultiplierOutside;
spline.noiseSizeX = spline.currentProfile.noiseSizeX;
spline.noiseSizeZ = spline.currentProfile.noiseSizeZ;
spline.terrainSmoothMultiplier = spline.currentProfile.terrainSmoothMultiplier;
spline.currentSplatMap = spline.currentProfile.currentSplatMap;
spline.mixTwoSplatMaps = spline.currentProfile.mixTwoSplatMaps;
spline.secondSplatMap = spline.currentProfile.secondSplatMap;
spline.addCliffSplatMap = spline.currentProfile.addCliffSplatMap;
spline.cliffSplatMap = spline.currentProfile.cliffSplatMap;
spline.cliffAngle = spline.currentProfile.cliffAngle;
spline.cliffBlend = spline.currentProfile.cliffBlend;
spline.cliffSplatMapOutside = spline.currentProfile.cliffSplatMapOutside;
spline.cliffAngleOutside = spline.currentProfile.cliffAngleOutside;
spline.cliffBlendOutside = spline.currentProfile.cliffBlendOutside;
spline.distanceClearFoliage = spline.currentProfile.distanceClearFoliage;
spline.distanceClearFoliageTrees = spline.currentProfile.distanceClearFoliageTrees;
spline.noisePaint = spline.currentProfile.noisePaint;
spline.noiseMultiplierInsidePaint = spline.currentProfile.noiseMultiplierInsidePaint;
spline.noiseMultiplierOutsidePaint = spline.currentProfile.noiseMultiplierOutsidePaint;
spline.noiseSizeXPaint = spline.currentProfile.noiseSizeXPaint;
spline.noiseSizeZPaint = spline.currentProfile.noiseSizeZPaint;
spline.simulatedRiverLength = spline.currentProfile.simulatedRiverLength;
spline.simulatedRiverPoints = spline.currentProfile.simulatedRiverPoints;
spline.simulatedMinStepSize = spline.currentProfile.simulatedMinStepSize;
spline.simulatedNoUp = spline.currentProfile.simulatedNoUp;
spline.simulatedBreakOnUp = spline.currentProfile.simulatedBreakOnUp;
spline.noiseWidth = spline.currentProfile.noiseWidth;
spline.noiseMultiplierWidth = spline.currentProfile.noiseMultiplierWidth;
spline.noiseSizeWidth = spline.currentProfile.noiseSizeWidth;
spline.receiveShadows = spline.currentProfile.receiveShadows;
spline.shadowCastingMode = spline.currentProfile.shadowCastingMode;
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
spline.oldProfile = spline.currentProfile;
}
void DrawVertexColorsUI()
{
spline.drawOnMesh = true;
if (spline.drawOnMesh)
{
EditorGUILayout.HelpBox("R - Slow Water G - Small Cascade B - Big Cascade A - Opacity", MessageType.Info);
EditorGUILayout.Space();
spline.drawColor = EditorGUILayout.ColorField("Draw color", spline.drawColor);
spline.opacity = EditorGUILayout.FloatField("Opacity", spline.opacity);
spline.drawSize = EditorGUILayout.FloatField("Size", spline.drawSize);
if (spline.drawSize < 0)
{
spline.drawSize = 0;
}
spline.drawColorR = EditorGUILayout.Toggle("Draw R", spline.drawColorR);
spline.drawColorG = EditorGUILayout.Toggle("Draw G", spline.drawColorG);
spline.drawColorB = EditorGUILayout.Toggle("Draw B", spline.drawColorB);
spline.drawColorA = EditorGUILayout.Toggle("Draw A", spline.drawColorA);
EditorGUILayout.Space();
spline.drawOnMultiple = EditorGUILayout.Toggle("Draw on multiple rivers", spline.drawOnMultiple);
}
EditorGUILayout.Space();
if (!spline.showVertexColors)
{
if (GUILayout.Button("Show vertex colors"))
{
if (!spline.showFlowMap && !spline.showVertexColors)
spline.oldMaterial = spline.GetComponent<MeshRenderer>().sharedMaterial;
ResetMaterial();
spline.GetComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("NatureManufacture Shaders/Debug/Vertex color"));
spline.showVertexColors = true;
}
}
else
{
if (GUILayout.Button("Hide vertex colors"))
{
ResetMaterial();
spline.GetComponent<MeshRenderer>().sharedMaterial = spline.oldMaterial;
spline.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"))
{
spline.colors = null;
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
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);
spline.drawOnMeshFlowMap = true;
if (spline.drawOnMeshFlowMap)
{
EditorGUILayout.Space();
spline.flowSpeed = EditorGUILayout.Slider("Flow U Speed", spline.flowSpeed, -1, 1);
spline.flowDirection = EditorGUILayout.Slider("Flow V Speed", spline.flowDirection, -1, 1);
spline.opacity = EditorGUILayout.FloatField("Opacity", spline.opacity);
spline.drawSize = EditorGUILayout.FloatField("Size", spline.drawSize);
if (spline.drawSize < 0)
{
spline.drawSize = 0;
}
EditorGUILayout.Space();
spline.drawOnMultiple = EditorGUILayout.Toggle("Draw on multiple rivers", spline.drawOnMultiple);
}
EditorGUILayout.Space();
if (!spline.showFlowMap)
{
if (GUILayout.Button("Show flow directions"))
{
if (!spline.showFlowMap && !spline.showVertexColors)
spline.oldMaterial = spline.GetComponent<MeshRenderer>().sharedMaterial;
ResetMaterial();
spline.GetComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("NatureManufacture Shaders/Debug/Flowmap Direction"));
spline.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_Direction", Resources.Load<Texture2D>("Debug_Arrow"));
spline.showFlowMap = true;
}
if (GUILayout.Button("Show flow smoothness"))
{
if (!spline.showFlowMap && !spline.showVertexColors)
spline.oldMaterial = spline.GetComponent<MeshRenderer>().sharedMaterial;
ResetMaterial();
spline.GetComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("NatureManufacture Shaders/Debug/FlowMapUV4"));
spline.showFlowMap = true;
}
}
if (spline.showFlowMap)
{
if (GUILayout.Button("Hide flow"))
{
ResetMaterial();
spline.GetComponent<MeshRenderer>().sharedMaterial = spline.oldMaterial;
}
}
EditorGUILayout.Space();
GUILayout.Label("Flow Map Automatic: ", EditorStyles.boldLabel);
spline.flowFlat = EditorGUILayout.CurveField("Flow curve flat speed", spline.flowFlat);
spline.flowWaterfall = EditorGUILayout.CurveField("Flow curve waterfall speed", spline.flowWaterfall);
spline.noiseflowMap = EditorGUILayout.Toggle("Add noise", spline.noiseflowMap);
if (spline.noiseflowMap)
{
EditorGUI.indentLevel++;
spline.noiseMultiplierflowMap = EditorGUILayout.FloatField("Noise multiplier inside", spline.noiseMultiplierflowMap);
spline.noiseSizeXflowMap = EditorGUILayout.FloatField("Noise scale X", spline.noiseSizeXflowMap);
spline.noiseSizeZflowMap = EditorGUILayout.FloatField("Noise scale Z", spline.noiseSizeZflowMap);
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
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"))
{
spline.overrideFlowMap = false;
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
EditorGUILayout.Space();
GUILayout.Label("Flow Map Physic: ", EditorStyles.boldLabel);
spline.floatSpeed = EditorGUILayout.FloatField("River float speed", spline.floatSpeed);
}
void ResetMaterial()
{
//if (spline.oldMaterial != null)
// spline.GetComponent<MeshRenderer> ().sharedMaterial = spline.oldMaterial;
spline.showFlowMap = false;
spline.showVertexColors = false;
}
void FilesManager()
{
if (GUILayout.Button("Save points to csv file"))
{
PointsToFile();
}
if (GUILayout.Button("Load points from csv file"))
{
PointsFromFile();
}
}
void Tips()
{
EditorGUILayout.Space();
EditorGUILayout.HelpBox("\nReflections - Use box projection in reflection probes to get proper render even at multiple river conection.\n", MessageType.Info);
EditorGUILayout.HelpBox("\nKeep resonable quasi- square vertex shapes at river mesh, " + "this will give better tesselation result. Don't worry about low amount of poly, tesselation will smooth shapes.\n", MessageType.Info);
EditorGUILayout.HelpBox("\nBy rotating point you could get simmilar effect as vertex color painting.\n" + "You could adjust waterfalls or add noise in the river. " + "Note that if rotation will be bigger then +/- 90 degree you could invert normals.\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.HelpBox("\nTry to keep quite simmilar distance between spline points. Huge distance between them could create strange result.\n", MessageType.Info);
EditorGUILayout.HelpBox("\nWhen you use multiple connected rivers, you shoud put reflection probe at fork of the rivers to keep proper reflections\n", MessageType.Info);
EditorGUILayout.Space();
}
void ParentingSplineUI()
{
GUILayout.Label("Rivers connections", EditorStyles.boldLabel);
spline.beginningSpline = (RamSpline)EditorGUILayout.ObjectField("Beginning spline", spline.beginningSpline, typeof(RamSpline), true);
if (spline.beginningSpline == spline)
spline.beginningSpline = null;
spline.endingSpline = (RamSpline)EditorGUILayout.ObjectField("Ending spline", spline.endingSpline, typeof(RamSpline), true);
if (spline.endingSpline == spline)
spline.endingSpline = null;
if (spline.beginningSpline != null)
{
if (spline.controlPoints.Count > 0 && spline.beginningSpline.points.Count > 0)
{
spline.beginningMinWidth = spline.beginningMinWidth * (spline.beginningSpline.vertsInShape - 1);
spline.beginningMaxWidth = spline.beginningMaxWidth * (spline.beginningSpline.vertsInShape - 1);
EditorGUILayout.MinMaxSlider("Part parent", ref spline.beginningMinWidth, ref spline.beginningMaxWidth, 0, spline.beginningSpline.vertsInShape - 1);
spline.beginningMinWidth = (int)spline.beginningMinWidth;
spline.beginningMaxWidth = (int)spline.beginningMaxWidth;
spline.beginningMinWidth = Mathf.Clamp(spline.beginningMinWidth, 0, spline.beginningSpline.vertsInShape - 1);
spline.beginningMaxWidth = Mathf.Clamp(spline.beginningMaxWidth, 0, spline.beginningSpline.vertsInShape - 1);
if (spline.beginningMinWidth == spline.beginningMaxWidth)
{
if (spline.beginningMinWidth > 0)
spline.beginningMinWidth--;
else
spline.beginningMaxWidth++;
}
spline.vertsInShape = (int)(spline.beginningMaxWidth - spline.beginningMinWidth) + 1;
spline.beginningMinWidth = spline.beginningMinWidth / (float)(spline.beginningSpline.vertsInShape - 1);
spline.beginningMaxWidth = spline.beginningMaxWidth / (float)(spline.beginningSpline.vertsInShape - 1);
spline.GenerateBeginningParentBased();
}
}
else
{
spline.beginningMaxWidth = 1;
spline.beginningMinWidth = 0;
}
if (spline.endingSpline != null)
{
if (spline.controlPoints.Count > 1 && spline.endingSpline.points.Count > 0)
{
spline.endingMinWidth = spline.endingMinWidth * (spline.endingSpline.vertsInShape - 1);
spline.endingMaxWidth = spline.endingMaxWidth * (spline.endingSpline.vertsInShape - 1);
EditorGUILayout.MinMaxSlider("Part parent", ref spline.endingMinWidth, ref spline.endingMaxWidth, 0, spline.endingSpline.vertsInShape - 1);
spline.endingMinWidth = (int)spline.endingMinWidth;
spline.endingMaxWidth = (int)spline.endingMaxWidth;
spline.endingMinWidth = Mathf.Clamp(spline.endingMinWidth, 0, spline.endingSpline.vertsInShape - 1);
spline.endingMaxWidth = Mathf.Clamp(spline.endingMaxWidth, 0, spline.endingSpline.vertsInShape - 1);
if (spline.endingMinWidth == spline.endingMaxWidth)
{
if (spline.endingMinWidth > 0)
spline.endingMinWidth--;
else
spline.endingMaxWidth++;
}
spline.vertsInShape = (int)(spline.endingMaxWidth - spline.endingMinWidth) + 1;
spline.endingMinWidth = spline.endingMinWidth / (float)(spline.endingSpline.vertsInShape - 1);
spline.endingMaxWidth = spline.endingMaxWidth / (float)(spline.endingSpline.vertsInShape - 1);
spline.GenerateEndingParentBased();
}
}
else
{
spline.endingMaxWidth = 1;
spline.endingMinWidth = 0;
}
}
void PointsUI()
{
if (GUILayout.Button(new GUIContent("Remove all points", "Removes all points")))
{
spline.RemovePoints();
}
for (int i = 0; i < spline.controlPoints.Count; i++)
{
GUILayout.Label("Point: " + i.ToString(), EditorStyles.boldLabel);
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
spline.controlPoints[i] = EditorGUILayout.Vector4Field("", spline.controlPoints[i]);
if (spline.controlPoints[i].w <= 0)
{
Vector4 vec4 = spline.controlPoints[i];
vec4.w = 0;
spline.controlPoints[i] = vec4;
}
if (GUILayout.Button(new GUIContent("A", "Add point after this point"), GUILayout.MaxWidth(20)))
{
spline.AddPointAfter(i);
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
if (GUILayout.Button(new GUIContent("R", "Remove this Point"), GUILayout.MaxWidth(20)))
{
spline.RemovePoint(i);
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
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.BeginHorizontal();
if (spline.controlPointsRotations.Count > i)
spline.controlPointsRotations[i] = Quaternion.Euler(EditorGUILayout.Vector3Field("", spline.controlPointsRotations[i].eulerAngles));
if (GUILayout.Button(new GUIContent(" Clear rotation ", "Clear Rotation")))
{
spline.controlPointsRotations[i] = Quaternion.identity;
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
EditorGUILayout.EndHorizontal();
if (spline.controlPointsSnap.Count > i)
spline.controlPointsSnap[i] = EditorGUILayout.Toggle("Snap to terrain", spline.controlPointsSnap[i] == 1 ? true : false) == true ? 1 : 0;
if (spline.controlPointsMeshCurves.Count > i)
spline.controlPointsMeshCurves[i] = EditorGUILayout.CurveField("Mesh curve", spline.controlPointsMeshCurves[i]);
EditorGUILayout.Space();
EditorGUI.indentLevel--;
}
}
void SetMaterials()
{
GUILayout.Label("Set materials: ", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("Basic", GUILayout.MinWidth(80)))
{
try
{
string materialName = "RAM_River_Material_Gamma";
if (PlayerSettings.colorSpace == ColorSpace.Linear)
materialName = "RAM_River_Material_Linear";
Material riverMat = (Material)Resources.Load(materialName);
if (riverMat != null)
{
spline.GetComponent<MeshRenderer>().sharedMaterial = riverMat;
}
}
catch
{
}
}
if (GUILayout.Button("Vertex color", GUILayout.MinWidth(80)))
{
try
{
string materialName = "RAM_River_Material_Gamma_Vertex_Color";
if (PlayerSettings.colorSpace == ColorSpace.Linear)
materialName = "RAM_River_Material_Linear_Vertex_Color";
Material riverMat = (Material)Resources.Load(materialName);
if (riverMat != null)
{
spline.GetComponent<MeshRenderer>().sharedMaterial = riverMat;
}
}
catch
{
}
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("Basic tesseled", GUILayout.MinWidth(80)))
{
try
{
string materialName = "RAM_River_Material_Gamma_Tess";
if (PlayerSettings.colorSpace == ColorSpace.Linear)
materialName = "RAM_River_Material_Linear_Tess";
Material riverMat = (Material)Resources.Load(materialName);
if (riverMat != null)
{
spline.GetComponent<MeshRenderer>().sharedMaterial = riverMat;
}
}
catch
{
}
}
if (GUILayout.Button("Basic tesseled - vertex color", GUILayout.MinWidth(80)))
{
try
{
string materialName = "RAM_River_Material_Gamma_Tess_Vertex_Color";
if (PlayerSettings.colorSpace == ColorSpace.Linear)
materialName = "RAM_River_Material_Linear_Tess_Vertex_Color";
Material riverMat = (Material)Resources.Load(materialName);
if (riverMat != null)
{
spline.GetComponent<MeshRenderer>().sharedMaterial = riverMat;
}
}
catch
{
}
}
}
EditorGUILayout.EndHorizontal();
}
void ChangePivot(Vector3 center)
{
Vector3 position = spline.transform.position;
spline.transform.position += center;
for (int i = 0; i < spline.controlPoints.Count; i++)
{
Vector4 vec = spline.controlPoints[i];
vec.x -= center.x;
vec.y -= center.y;
vec.z -= center.z;
spline.controlPoints[i] = vec;
}
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
protected virtual void OnSceneGUIInvoke(SceneView sceneView)
{
if (spline == null)
spline = (RamSpline)target;
Color baseColor = Handles.color;
int controlId = GUIUtility.GetControlID(FocusType.Passive);
if (spline != null)
{
Camera sceneCamera = SceneView.lastActiveSceneView.camera;
CheckRotations();
if (spline.drawOnMesh || spline.drawOnMeshFlowMap)
{
Tools.current = Tool.None;
if (spline.meshfilter != null)
{
Handles.color = Color.magenta;
Vector3[] vertices = spline.meshfilter.sharedMesh.vertices;
Vector2[] uv4 = spline.meshfilter.sharedMesh.uv4;
Vector3[] normals = spline.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 = spline.transform.TransformPoint(item);
if (spline.drawOnMesh)
Handles.RectangleHandleCap(0, handlePos, up, 0.05f, EventType.Repaint);
}
}
if (spline.drawOnMesh)
DrawOnVertexColors();
else
DrawOnFlowMap();
return;
}
if (Event.current.commandName == "UndoRedoPerformed")
{
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
return;
}
if (selectedPosition >= 0 && selectedPosition < spline.controlPoints.Count)
{
Handles.color = Color.red;
Handles.SphereHandleCap(0, (Vector3)spline.controlPoints[selectedPosition] + spline.transform.position, Quaternion.identity, 1, EventType.Repaint);
}
if (spline.debug)
{
ShowDebugHandles();
}
int controlPointToDelete = -1;
for (int j = 0; j < spline.controlPoints.Count; j++)
{
EditorGUI.BeginChangeCheck();
Vector3 handlePos = (Vector3)spline.controlPoints[j] + spline.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);
}
float width = spline.controlPoints[j].w;
if (Event.current.control && Event.current.shift && spline.controlPoints.Count > 1)
{
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)spline.controlPoints[j] + spline.transform.position, Quaternion.identity, size, EventType.Repaint);
}
else if (Event.current.type == EventType.Layout)
{
Handles.SphereHandleCap(id, (Vector3)spline.controlPoints[j] + spline.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;
Vector4 pos = Handles.Slider((Vector3)spline.controlPoints[j] + spline.transform.position, Vector3.right, size, Handles.ArrowHandleCap, 0.01f) - spline.transform.position;
Handles.color = Handles.yAxisColor;
pos = Handles.Slider((Vector3)pos + spline.transform.position, Vector3.up, size, Handles.ArrowHandleCap, 0.01f) - spline.transform.position;
Handles.color = Handles.zAxisColor;
pos = Handles.Slider((Vector3)pos + spline.transform.position, Vector3.forward, size, Handles.ArrowHandleCap, 0.01f) - spline.transform.position;
Vector3 halfPos = (Vector3.right + Vector3.forward) * size * 0.3f;
Handles.color = Handles.yAxisColor;
pos = Handles.Slider2D((Vector3)pos + spline.transform.position + halfPos, Vector3.up, Vector3.right, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - spline.transform.position - halfPos;
halfPos = (Vector3.right + Vector3.up) * size * 0.3f;
Handles.color = Handles.zAxisColor;
pos = Handles.Slider2D((Vector3)pos + spline.transform.position + halfPos, Vector3.forward, Vector3.right, Vector3.up, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - spline.transform.position - halfPos;
halfPos = (Vector3.up + Vector3.forward) * size * 0.3f;
Handles.color = Handles.xAxisColor;
pos = Handles.Slider2D((Vector3)pos + spline.transform.position + halfPos, Vector3.right, Vector3.up, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - spline.transform.position - halfPos;
pos.w = width;
spline.controlPoints[j] = pos;
}
else if (Tools.current == Tool.Rotate)
{
if (spline.controlPointsRotations.Count > j && spline.controlPointsOrientation.Count > j)
{
if (!((spline.beginningSpline && j == 0) || (spline.endingSpline && j == spline.controlPoints.Count - 1)))
{
float size = 0.6f;
size = HandleUtility.GetHandleSize(handlePos) * size;
Handles.color = Handles.zAxisColor;
Quaternion rotation = Handles.Disc(spline.controlPointsOrientation[j], handlePos, spline.controlPointsOrientation[j] * new Vector3(0, 0, 1), size, true, 0.1f);
Handles.color = Handles.yAxisColor;
rotation = Handles.Disc(rotation, handlePos, rotation * new Vector3(0, 1, 0), size, true, 0.1f);
Handles.color = Handles.xAxisColor;
rotation = Handles.Disc(rotation, handlePos, rotation * new Vector3(1, 0, 0), size, true, 0.1f);
spline.controlPointsRotations[j] *= (Quaternion.Inverse(spline.controlPointsOrientation[j]) * rotation);
if (float.IsNaN(spline.controlPointsRotations[j].x) || float.IsNaN(spline.controlPointsRotations[j].y) || float.IsNaN(spline.controlPointsRotations[j].z) || float.IsNaN(spline.controlPointsRotations[j].w))
{
spline.controlPointsRotations[j] = Quaternion.identity;
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
Handles.color = baseColor;
Handles.FreeRotateHandle(Quaternion.identity, handlePos, size);
Handles.CubeHandleCap(0, handlePos, spline.controlPointsOrientation[j], size * 0.3f, EventType.Repaint);
Handles.DrawLine(spline.controlPointsUp[j] + spline.transform.position, spline.controlPointsDown[j] + spline.transform.position);
}
}
}
else if (Tools.current == Tool.Scale)
{
Handles.color = Handles.xAxisColor;
//Vector3 handlePos = (Vector3)spline.controlPoints [j] + spline.transform.position;
width = Handles.ScaleSlider(spline.controlPoints[j].w, (Vector3)spline.controlPoints[j] + spline.transform.position, new Vector3(0, 0.5f, 0),
Quaternion.Euler(-90, 0, 0), HandleUtility.GetHandleSize(handlePos), 0.01f);
Vector4 pos = spline.controlPoints[j];
pos.w = width;
spline.controlPoints[j] = pos;
}
if (EditorGUI.EndChangeCheck())
{
CheckRotations();
Undo.RecordObject(spline, "Change Position");
spline.GenerateSpline();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
if (controlPointToDelete >= 0)
{
Undo.RecordObject(spline, "Remove point");
spline.RemovePoint(controlPointToDelete);
spline.GenerateSpline();
GUIUtility.hotControl = controlId;
Event.current.Use();
HandleUtility.Repaint();
controlPointToDelete = -1;
}
if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.control && !Event.current.shift)
{
Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Undo.RecordObject(spline, "Add point");
Vector4 position = hit.point - spline.transform.position;
if (!Event.current.alt)
spline.AddPoint(position);
else
{
spline.AddPointAfter(-1);
spline.ChangePointPosition(0, position);
spline.GenerateSpline();
}
spline.GenerateSpline();
GUIUtility.hotControl = controlId;
Event.current.Use();
HandleUtility.Repaint();
}
}
if (!Event.current.control && Event.current.shift && spline.controlPoints.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 < spline.controlPoints.Count; j++)
{
Vector3 handlePos = (Vector3)spline.controlPoints[j] + spline.transform.position;
float pointDist = Vector3.Distance(hit.point, handlePos);
if (pointDist < distanceMin)
{
distanceMin = pointDist;
idMin = j;
}
}
Vector3 posOne = (Vector3)spline.controlPoints[idMin] + spline.transform.position;
Vector3 posTwo;
if (idMin == 0)
{
posTwo = (Vector3)spline.controlPoints[1] + spline.transform.position;
}
else if (idMin == spline.controlPoints.Count - 1)
{
posTwo = (Vector3)spline.controlPoints[spline.controlPoints.Count - 2] + spline.transform.position;
idMin = idMin - 1;
}
else
{
Vector3 posPrev = (Vector3)spline.controlPoints[idMin - 1] + spline.transform.position;
Vector3 posNext = (Vector3)spline.controlPoints[idMin + 1] + spline.transform.position;
if (Vector3.Distance(hit.point, posPrev) > Vector3.Distance(hit.point, posNext))
posTwo = posNext;
else
{
posTwo = posPrev;
idMin = idMin - 1;
}
}
Handles.DrawLine(hit.point, posOne);
Handles.DrawLine(hit.point, posTwo);
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
Undo.RecordObject(spline, "Add point");
Vector4 position = hit.point - spline.transform.position;
spline.AddPointAfter(idMin);
spline.ChangePointPosition(idMin + 1, position);
spline.GenerateSpline();
GUIUtility.hotControl = controlId;
Event.current.Use();
HandleUtility.Repaint();
#if VEGETATION_STUDIO_PRO
RegeneratBiomeMask();
#endif
}
}
}
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;
}
}
}
private void ShowDebugHandles()
{
Vector3[] points = new Vector3[spline.controlPoints.Count];
for (int i = 0; i < spline.controlPoints.Count; i++)
{
points[i] = (Vector3)spline.controlPoints[i] + spline.transform.position;
}
Handles.color = Color.white;
Handles.DrawPolyLine(points);
Handles.color = new Color(1, 0, 0, 0.5f);
for (int i = 0; i < spline.pointsDown.Count; i++)
{
Vector3 handlePos = (Vector3)spline.pointsDown[i] + spline.transform.position;
Vector3 handlePos2 = (Vector3)spline.pointsUp[i] + spline.transform.position;
if (spline.debugPointsConnect)
Handles.DrawLine(handlePos, handlePos2);
}
Handles.color = Color.blue;
points = new Vector3[spline.pointsDown.Count];
for (int i = 0; i < spline.pointsDown.Count; i++)
{
if (spline.debugPoints)
Handles.SphereHandleCap(0, spline.pointsDown[i] + spline.transform.position, Quaternion.identity, 0.1f, EventType.Repaint);
points[i] = (Vector3)spline.pointsDown[i] + spline.transform.position;
}
Handles.DrawPolyLine(points);
points = new Vector3[spline.pointsUp.Count];
for (int i = 0; i < spline.pointsUp.Count; i++)
{
if (spline.debugPoints)
Handles.SphereHandleCap(0, spline.pointsUp[i] + spline.transform.position, Quaternion.identity, 0.1f, EventType.Repaint);
points[i] = (Vector3)spline.pointsUp[i] + spline.transform.position;
}
Handles.DrawPolyLine(points);
spline.debugMesh = true;
//Normals, tangents
//if (!spline.debugMesh)
//{
//points = spline.points.ToArray();
//for (int i = 0; i < points.Length; i++)
//{
// points[i] += spline.transform.position;
// Handles.color = Color.green;
// if (spline.debugNormals)
// {
// Handles.DrawLine(points[i], points[i] + spline.normalsList[i]);
// }
// if (spline.debugBitangent)
// {
// Vector3 posUp = spline.orientations[i] * Vector3.right;
// Handles.DrawLine(points[i], points[i] + posUp);
// }
// Handles.color = Color.red;
// if (spline.debugTangents)
// Handles.DrawLine(points[i] - spline.tangents[i], points[i] + spline.tangents[i]);
//}
//}
//else if (spline.debugMesh)
//{
Vector3 camPosition = SceneView.lastActiveSceneView.camera.transform.position;
GUIStyle style = new GUIStyle();
style.normal.textColor = Color.red;
Mesh mesh = spline.meshfilter.sharedMesh;
if (mesh)
{
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
Vector4[] tangents = mesh.tangents;
Vector2[] uv4 = mesh.uv4;
float distDebug = spline.distanceToDebug * spline.distanceToDebug;
for (int i = 0; i < vertices.Length; i++)
{
vertices[i] += spline.transform.position;
Vector3 offset = vertices[i] - camPosition;
float sqrLen = offset.sqrMagnitude;
if (sqrLen > distDebug)
continue;
Handles.color = Color.green;
if (spline.debugNormals)
{
Handles.DrawLine(vertices[i], vertices[i] + normals[i]);
}
Handles.color = Color.red;
if (spline.debugTangents)
Handles.DrawLine(vertices[i] - (Vector3)tangents[i], vertices[i] + (Vector3)tangents[i]);
Handles.color = Color.magenta;
if (spline.debugFlowmap)
{
Handles.DrawLine(vertices[i], vertices[i] + new Vector3(uv4[i].x, uv4[i].y, 0) * 2);
Handles.Label(vertices[i] + new Vector3(uv4[i].x, uv4[i].y, 0) * 2, uv4[i].x + " " + uv4[i].y, style);
}
}
}
//}
}
void DrawOnVertexColors()
{
if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
{
Undo.RegisterCompleteObjectUndo(spline, "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 = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
List<MeshCollider> meshColliders = new List<MeshCollider>();
foreach (var item in splines)
{
meshColliders.Add(item.gameObject.AddComponent<MeshCollider>());
}
RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity);
GameObject go = null;
Vector3 hitPosition = Vector3.zero;
Vector3 hitNormal = Vector3.zero;
RamSpline hitedSpline = null;
if (hits.Length > 0)
{
foreach (var hit in hits)
{
if (hit.collider is MeshCollider)
{
go = hit.collider.gameObject;
hitedSpline = go.GetComponent<RamSpline>();
if (hitedSpline != null && (spline.drawOnMultiple || hitedSpline == spline))
{
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(spline.drawColor.r, spline.drawColor.g, spline.drawColor.b, 1);
Handles.DrawLine(hitPosition, hitPosition + hitNormal * 2);
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
spline.drawSize,
EventType.Repaint
);
Handles.color = Color.black;
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
spline.drawSize - 0.1f,
EventType.Repaint
);
if (!(Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) || Event.current.button != 0)
return;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
}
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 (spline.drawColorR)
colors[i].r = Mathf.Lerp(colors[i].r, 0, spline.opacity);
if (spline.drawColorG)
colors[i].g = Mathf.Lerp(colors[i].g, 0, spline.opacity);
if (spline.drawColorB)
colors[i].b = Mathf.Lerp(colors[i].b, 0, spline.opacity);
if (spline.drawColorA)
colors[i].a = Mathf.Lerp(colors[i].a, 1, spline.opacity);
}
else
{
if (spline.drawColorR)
colors[i].r = Mathf.Lerp(colors[i].r, spline.drawColor.r, spline.opacity);
if (spline.drawColorG)
colors[i].g = Mathf.Lerp(colors[i].g, spline.drawColor.g, spline.opacity);
if (spline.drawColorB)
colors[i].b = Mathf.Lerp(colors[i].b, spline.drawColor.b, spline.opacity);
if (spline.drawColorA)
colors[i].a = Mathf.Lerp(colors[i].a, spline.drawColor.a, spline.opacity);
}
}
}
mesh.colors = colors;
meshFilter.sharedMesh = mesh;
if (hitedSpline.generateMeshParts)
hitedSpline.GenerateMeshParts(mesh);
}
}
}
void DrawOnFlowMap()
{
if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
{
Undo.RegisterCompleteObjectUndo(spline, "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 splines)
{
meshColliders.Add(item.gameObject.AddComponent<MeshCollider>());
}
RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity);
GameObject go = null;
Vector3 hitPosition = Vector3.zero;
Vector3 hitNormal = Vector3.zero;
RamSpline hitedSpline = null;
if (hits.Length > 0)
{
foreach (var hit in hits)
{
if (hit.collider is MeshCollider)
{
go = hit.collider.gameObject;
hitedSpline = go.GetComponent<RamSpline>();
if (hitedSpline != null && (spline.drawOnMultiple || hitedSpline == spline))
{
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(spline.flowDirection, spline.flowSpeed, 0, 1);
Handles.DrawLine(hitPosition, hitPosition + hitNormal * 2);
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
spline.drawSize,
EventType.Repaint
);
Handles.color = Color.black;
Handles.CircleHandleCap(
0,
hitPosition,
Quaternion.LookRotation(hitNormal),
spline.drawSize - 0.1f,
EventType.Repaint
);
if (!(Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) || Event.current.button != 0)
return;
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
{
}
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 < spline.drawSize)
{
distValue = (spline.drawSize - dist) / (float)spline.drawSize;
if (Event.current.shift)
{
colorsFlowMap[i] = Vector2.Lerp(colorsFlowMap[i], new Vector2(0, 0), spline.opacity);
}
else
{
colorsFlowMap[i] = Vector2.Lerp(colorsFlowMap[i], new Vector2(spline.flowDirection, spline.flowSpeed), spline.opacity * distValue);
}
}
}
mesh.uv4 = colorsFlowMap.ToArray();
hitedSpline.colorsFlowMap = colorsFlowMap;
meshFilter.sharedMesh = mesh;
if (hitedSpline.generateMeshParts)
hitedSpline.GenerateMeshParts(mesh);
}
}
}
public static LayerMask LayerMaskField(string label, LayerMask selected, bool showSpecial)
{
List<string> layers = new List<string>();
List<int> layerNumbers = new List<int>();
string selectedLayers = "";
for (int i = 0; i < 32; i++)
{
string layerName = LayerMask.LayerToName(i);
if (layerName != "")
{
if (selected == (selected | (1 << i)))
{
if (selectedLayers == "")
{
selectedLayers = layerName;
}
else
{
selectedLayers = "Mixed";
}
}
}
}
EventType lastEvent = Event.current.type;
if (Event.current.type != EventType.MouseDown && Event.current.type != EventType.ExecuteCommand)
{
if (selected.value == 0)
{
layers.Add("Nothing");
}
else if (selected.value == -1)
{
layers.Add("Everything");
}
else
{
layers.Add(selectedLayers);
}
layerNumbers.Add(-1);
}
if (showSpecial)
{
layers.Add((selected.value == 0 ? "[X] " : " ") + "Nothing");
layerNumbers.Add(-2);
layers.Add((selected.value == -1 ? "[X] " : " ") + "Everything");
layerNumbers.Add(-3);
}
for (int i = 0; i < 32; i++)
{
string layerName = LayerMask.LayerToName(i);
if (layerName != "")
{
if (selected == (selected | (1 << i)))
{
layers.Add("[X] " + i + ": " + layerName);
}
else
{
layers.Add(" " + i + ": " + layerName);
}
layerNumbers.Add(i);
}
}
bool preChange = GUI.changed;
GUI.changed = false;
int newSelected = 0;
if (Event.current.type == EventType.MouseDown)
{
newSelected = -1;
}
newSelected = EditorGUILayout.Popup(label, newSelected, layers.ToArray(), EditorStyles.layerMaskField);
if (GUI.changed && newSelected >= 0)
{
if (showSpecial && newSelected == 0)
{
selected = 0;
}
else if (showSpecial && newSelected == 1)
{
selected = -1;
}
else
{
if (selected == (selected | (1 << layerNumbers[newSelected])))
{
selected &= ~(1 << layerNumbers[newSelected]);
}
else
{
selected = selected | (1 << layerNumbers[newSelected]);
}
}
}
else
{
GUI.changed = preChange;
}
return selected;
}
public void PointsToFile()
{
var path = EditorUtility.SaveFilePanelInProject(
"Save Spline Points",
spline.name + "Points.csv",
"csv",
"Save Spline " + spline.name + " Points in CSV");
if (string.IsNullOrEmpty(path))
return;
string fileData = "";
foreach (Vector4 v in spline.controlPoints)
{
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 Spline 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(spline, "Spline changed");
if (vectors.Length > 0)
{
foreach (var item in vectors)
{
spline.AddPoint(item);
}
}
}
}