using System.Collections.Generic; using UnityEngine; public class e2dTerrainCurveMesh : e2dTerrainMesh { public List ControlTextures; public List StripeVertices; public MeshRenderer renderer { get { EnsureMeshComponentsExist(); return base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent(); } } public GameObject gameObject { get { return base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).gameObject; } } public e2dTerrainCurveMesh(e2dTerrain terrain) : base(terrain) { ControlTextures = new List(); StripeVertices = new List(); } public void RebuildMesh() { if (base.TerrainCurve.Count < 2 || base.Terrain.CurveIntercrossing) { DestroyMesh(); return; } EnsureMeshComponentsExist(); ResetMeshObjectsTransforms(); Vector3[] array = new Vector3[base.TerrainCurve.Count * 2]; Vector3[] array2 = new Vector3[array.Length]; Vector2[] array3 = new Vector2[array.Length]; Vector2[] array4 = new Vector2[array.Length]; Color[] array5 = new Color[array.Length]; int[] array6 = new int[(base.TerrainCurve.Count - 1) * 2 * 3]; StripeVertices = ComputeStripeVertices(); array[0] = base.TerrainCurve[0].position; array[1] = StripeVertices[0]; array2[0] = Vector3.back; array2[1] = Vector3.back; array3[0] = new Vector2(0f, 0f); array3[1] = new Vector2(0f, 0f); array4[0] = array[0]; array4[1] = array[1]; array5[0] = new Color(1f, 0f, 0f, 0f); array5[1] = new Color(0f, 0f, 0f, 0f); float num = 0f; for (int i = 1; i < base.TerrainCurve.Count; i++) { int num2 = i; int num3 = 2 * num2; int num4 = 6 * (i - 1); float magnitude = (base.TerrainCurve[i].position - base.TerrainCurve[i - 1].position).magnitude; num += magnitude; Vector3 vector = Vector3.back; if (base.Terrain.PlasticEdges && i < base.TerrainCurve.Count - 1) { Vector2 normalized = (base.TerrainCurve[i].position - base.TerrainCurve[i - 1].position).normalized; Vector2 normalized2 = (base.TerrainCurve[i + 1].position - base.TerrainCurve[i].position).normalized; Vector2 normalized3 = (normalized + normalized2).normalized; vector = new Vector3(0f - normalized3.y, normalized3.x, -1f); } array[num3] = base.TerrainCurve[num2].position; array[num3] -= Vector3.forward * 0.01f; array2[num3] = vector; array3[num3] = new Vector2(num, num2); array4[num3] = array[num3]; array5[num3] = new Color(1f, 0f, 0f, 0f); array[num3 + 1] = StripeVertices[i]; array2[num3 + 1] = Vector3.back; array3[num3 + 1] = new Vector2(num, num2); array4[num3 + 1] = array[num3 + 1]; array5[num3 + 1] = new Color(0f, 0f, 0f, 0f); if (e2dUtils.PointInTriangle(array[num3 + 1], array[num3 - 2], array[num3], array[num3 - 1])) { array6[num4] = num3 - 2; array6[num4 + 1] = num3 + 1; array6[num4 + 2] = num3 - 1; array6[num4 + 3] = num3 - 2; array6[num4 + 4] = num3; array6[num4 + 5] = num3 + 1; } else { array6[num4] = num3 - 2; array6[num4 + 1] = num3; array6[num4 + 2] = num3 - 1; array6[num4 + 3] = num3 - 1; array6[num4 + 4] = num3; array6[num4 + 5] = num3 + 1; } } MeshFilter component = base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent(); component.sharedMesh.Clear(); component.sharedMesh.vertices = array; component.sharedMesh.normals = array2; component.sharedMesh.uv = array3; component.sharedMesh.uv2 = array4; component.sharedMesh.colors = array5; component.sharedMesh.triangles = array6; if (SomeMaterialsMissing()) { RebuildMaterial(); } } private List ComputeStripeVertices() { List list = new List(base.TerrainCurve.Count); list.Add(ComputeFirstStripeVertex()); for (int i = 1; i < base.TerrainCurve.Count - 1; i++) { list.Add(ComputeStripeVertex(i)); } list.Add(ComputeLastStripeVertex()); for (int j = 0; j < list.Count - 1; j++) { for (int k = j + 2; k < list.Count - 1; k++) { Vector2 intersection; if (e2dUtils.SegmentsIntersect(list[j], list[j + 1], list[k], list[k + 1], out intersection)) { for (int l = j + 1; l <= k; l++) { list[l] = intersection; } break; } } } return list; } private Vector3 ComputeFirstStripeVertex() { Vector2 point = base.TerrainCurve[0].position; base.Boundary.ProjectStartPointToBoundary(ref point); Vector3 point2 = point; if (point != base.TerrainCurve[0].position) { Vector2 vector = base.TerrainCurve[1].position - base.TerrainCurve[0].position; Vector2 vector2 = GetNodeStripeSize(0) * new Vector2(vector.y, 0f - vector.x).normalized; Vector2 b = point - base.TerrainCurve[0].position; Vector2 result; if (!e2dUtils.HalfLineAndLineIntersect(Vector2.zero, b, vector2, vector2 + vector, out result)) { result = Vector2.zero; } point2 = base.TerrainCurve[0].position + result; base.Boundary.EnsurePointIsInBoundary(ref point2); } return point2; } private Vector3 ComputeLastStripeVertex() { Vector2 point = base.TerrainCurve[base.TerrainCurve.Count - 1].position; base.Boundary.ProjectEndPointToBoundary(ref point); Vector3 point2 = point; if (point != base.TerrainCurve[base.TerrainCurve.Count - 1].position) { Vector2 vector = base.TerrainCurve[base.TerrainCurve.Count - 1].position - base.TerrainCurve[base.TerrainCurve.Count - 2].position; Vector2 vector2 = GetNodeStripeSize(base.TerrainCurve.Count - 1) * new Vector2(vector.y, 0f - vector.x).normalized; Vector2 b = point - base.TerrainCurve[base.TerrainCurve.Count - 1].position; Vector2 result; if (!e2dUtils.HalfLineAndLineIntersect(Vector2.zero, b, vector2, vector2 + vector, out result)) { result = Vector2.zero; } point2 = base.TerrainCurve[base.TerrainCurve.Count - 1].position + result; base.Boundary.EnsurePointIsInBoundary(ref point2); } return point2; } private Vector3 ComputeStripeVertex(int nodeIndex) { Vector2 vector = base.TerrainCurve[nodeIndex].position - base.TerrainCurve[nodeIndex - 1].position; Vector2 vector2 = base.TerrainCurve[nodeIndex + 1].position - base.TerrainCurve[nodeIndex].position; Vector2 normalized = new Vector2(vector.y, 0f - vector.x).normalized; Vector2 normalized2 = new Vector2(vector2.y, 0f - vector2.x).normalized; Vector2 vector3 = GetNodeStripeSize(nodeIndex) * (normalized + normalized2).normalized; Vector3 point = base.TerrainCurve[nodeIndex].position + vector3; base.Boundary.EnsurePointIsInBoundary(ref point); return point; } private float GetNodeStripeSize(int nodeIndex) { e2dCurveTexture e2dCurveTexture2 = base.CurveTextures[base.TerrainCurve[nodeIndex].texture]; return e2dCurveTexture2.size.y; } public void DestroyMesh() { EnsureMeshObjectsExist(); DestroyTemporaryAssets(); MeshFilter component = base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent(); if ((bool)component && component.sharedMesh != null) { Object.DestroyImmediate(component.sharedMesh); } MeshRenderer component2 = base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent(); if ((bool)component2 && component2.sharedMaterials != null) { Material[] sharedMaterials = component2.sharedMaterials; foreach (Material obj in sharedMaterials) { Object.DestroyImmediate(obj); } } } public void RebuildMaterial() { EnsureMeshComponentsExist(); MeshRenderer component = base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent(); Material[] sharedMaterials = component.sharedMaterials; if (sharedMaterials != null) { Material[] array = sharedMaterials; foreach (Material obj in array) { Object.DestroyImmediate(obj, true); } } EnsureTexturesInited(); int materialsNeededCount = GetMaterialsNeededCount(); sharedMaterials = new Material[materialsNeededCount]; if (ControlTextures.Count != materialsNeededCount) { UpdateControlTextures(); } int num = 0; for (int j = 0; j < materialsNeededCount; j++) { sharedMaterials[j] = new Material(Shader.Find("e2d/Curve")); sharedMaterials[j].SetFloat("_ControlSize", ControlTextures[j].width); sharedMaterials[j].SetTexture("_Control", ControlTextures[j]); int num2 = 0; while (num2 < e2dConstants.NUM_TEXTURES_PER_STRIPE_SHADER && num < base.CurveTextures.Count) { sharedMaterials[j].SetTexture("_Splat" + num2, base.CurveTextures[num].texture); Vector4 vector = new Vector4(base.CurveTextures[num].size.x, base.CurveTextures[num].size.y, base.CurveTextures[num].fixedAngle ? 1 : 0, base.CurveTextures[num].fadeThreshold); sharedMaterials[j].SetVector("_SplatParams" + num2, vector); num2++; num++; } } component.materials = sharedMaterials; } private void EnsureTexturesInited() { if (base.CurveTextures.Count != 0) { return; } base.CurveTextures.Clear(); base.CurveTextures.Add(GetDefaultCurveTexture()); foreach (Texture2D controlTexture in ControlTextures) { Object.DestroyImmediate(controlTexture, true); } ControlTextures.Clear(); ControlTextures.Add(CreateControlTexture(new Color(1f, 0f, 0f, 0f))); } public void UpdateControlTextures() { UpdateControlTextures(false); } public void UpdateControlTextures(bool forceRecreate) { while (ControlTextures.Count > GetMaterialsNeededCount()) { Object.DestroyImmediate(ControlTextures[ControlTextures.Count - 1], true); ControlTextures.RemoveAt(ControlTextures.Count - 1); } while (ControlTextures.Count < GetMaterialsNeededCount()) { ControlTextures.Add(CreateControlTexture(new Color(0f, 0f, 0f, 0f))); } for (int i = 0; i < ControlTextures.Count; i++) { if (forceRecreate || ControlTextures[i] == null || ControlTextures[i].width != GetControlTextureSize()) { Object.DestroyImmediate(ControlTextures[i], true); ControlTextures[i] = CreateControlTexture(new Color(0f, 0f, 0f, 0f)); EnsureMeshComponentsExist(); MeshRenderer component = base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent(); if (component.sharedMaterials != null && i == component.sharedMaterials.Length - 1 && (bool)component.sharedMaterials[i]) { component.sharedMaterials[i].SetFloat("_ControlSize", ControlTextures[i].width); component.sharedMaterials[i].SetTexture("_Control", ControlTextures[i]); } } if (base.TerrainCurve.Count == 0) { break; } Color[] array = new Color[base.TerrainCurve.Count]; for (int j = 0; j < base.TerrainCurve.Count; j++) { array[j] = new Color(0f, 0f, 0f, 0f); if (base.TerrainCurve[j].texture / e2dConstants.NUM_TEXTURES_PER_STRIPE_SHADER == i) { switch (base.TerrainCurve[j].texture % e2dConstants.NUM_TEXTURES_PER_STRIPE_SHADER) { case 0: array[j].r = 1f; break; case 1: array[j].g = 1f; break; case 2: array[j].b = 1f; break; case 3: array[j].a = 1f; break; } } } ControlTextures[i].SetPixels(0, 0, array.Length, 1, array); ControlTextures[i].Apply(); } } private int GetMaterialsNeededCount() { int num = base.CurveTextures.Count / e2dConstants.NUM_TEXTURES_PER_STRIPE_SHADER; if (base.CurveTextures.Count % e2dConstants.NUM_TEXTURES_PER_STRIPE_SHADER != 0) { num++; } return num; } private int GetControlTextureSize() { int num = Mathf.NextPowerOfTwo(base.TerrainCurve.Count); if (num == 0) { num = 1; } return num; } private Texture2D CreateControlTexture(Color color) { int controlTextureSize = GetControlTextureSize(); Texture2D texture2D = new Texture2D(controlTextureSize, 1, TextureFormat.ARGB32, false); texture2D.filterMode = FilterMode.Bilinear; texture2D.wrapMode = TextureWrapMode.Clamp; texture2D.anisoLevel = 1; Color[] array = new Color[controlTextureSize]; for (int i = 0; i < controlTextureSize; i++) { array[i] = color; } texture2D.SetPixels(array); texture2D.Apply(); return texture2D; } public e2dCurveTexture GetDefaultCurveTexture() { return new e2dCurveTexture((Texture)Resources.Load("defaultCurveTexture", typeof(Texture))); } public bool SomeMaterialsMissing() { return base.transform.FindChild(e2dConstants.CURVE_MESH_NAME).GetComponent().sharedMaterial == null; } public void AppendCurveTexture() { base.Terrain.CurveTextures.Add(base.Terrain.CurveMesh.GetDefaultCurveTexture()); UpdateControlTextures(); } public void RemoveCurveTexture(int index) { base.Terrain.CurveTextures.RemoveAt(index); foreach (e2dCurveNode item in base.TerrainCurve) { if (item.texture == index) { item.texture = 0; } else if (item.texture > index) { item.texture--; } } UpdateControlTextures(); } public void DestroyTemporaryAssets() { foreach (Texture2D controlTexture in ControlTextures) { if ((bool)controlTexture) { Object.DestroyImmediate(controlTexture, true); } } ControlTextures.Clear(); } }