rise-and-swine/Assets/Scripts/Assembly-CSharp/e2dTerrainCurveMesh.cs
2023-02-25 23:04:03 -05:00

415 lines
13 KiB
C#

using System.Collections.Generic;
using UnityEngine;
public class e2dTerrainCurveMesh : e2dTerrainMesh
{
public e2dTerrainCurveMesh(e2dTerrain terrain) : base(terrain)
{
this.ControlTextures = new List<Texture2D>();
this.StripeVertices = new List<Vector3>();
}
public MeshRenderer renderer
{
get
{
base.EnsureMeshComponentsExist();
return base.transform.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshRenderer>();
}
}
public GameObject gameObject
{
get
{
return base.transform.Find(e2dConstants.CURVE_MESH_NAME).gameObject;
}
}
public void RebuildMesh()
{
if (base.TerrainCurve.Count < 2 || base.Terrain.CurveIntercrossing)
{
this.DestroyMesh();
return;
}
base.EnsureMeshComponentsExist();
base.ResetMeshObjectsTransforms();
Vector3[] array = new Vector3[base.TerrainCurve.Count * 2];
Vector2[] array2 = new Vector2[array.Length];
Color[] array3 = new Color[array.Length];
int[] array4 = new int[(base.TerrainCurve.Count - 1) * 2 * 3];
this.StripeVertices = this.ComputeStripeVertices();
array[0] = base.TerrainCurve[0].position;
array[1] = this.StripeVertices[0];
array2[0] = new Vector2(0f, 0f);
array2[1] = new Vector2(0f, 0f);
array3[0] = new Color(1f, 0f, 0f, 0f);
array3[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;
array[num3] = base.TerrainCurve[num2].position;
array[num3] -= Vector3.forward * 0.01f;
array2[num3] = new Vector2(num, (float)num2);
array3[num3] = new Color(1f, 0f, 0f, 0f);
array[num3 + 1] = this.StripeVertices[i];
array2[num3 + 1] = new Vector2(num, (float)num2);
array3[num3 + 1] = new Color(0f, 0f, 0f, 0f);
if (e2dUtils.PointInTriangle(array[num3 + 1], array[num3 - 2], array[num3], array[num3 - 1]))
{
array4[num4] = num3 - 2;
array4[num4 + 1] = num3 + 1;
array4[num4 + 2] = num3 - 1;
array4[num4 + 3] = num3 - 2;
array4[num4 + 4] = num3;
array4[num4 + 5] = num3 + 1;
}
else
{
array4[num4] = num3 - 2;
array4[num4 + 1] = num3;
array4[num4 + 2] = num3 - 1;
array4[num4 + 3] = num3 - 1;
array4[num4 + 4] = num3;
array4[num4 + 5] = num3 + 1;
}
}
MeshFilter component = base.transform.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshFilter>();
component.sharedMesh.Clear();
component.sharedMesh.vertices = array;
component.sharedMesh.uv = array2;
component.sharedMesh.colors = array3;
component.sharedMesh.triangles = array4;
if (this.SomeMaterialsMissing())
{
this.RebuildMaterial();
}
}
private List<Vector3> ComputeStripeVertices()
{
List<Vector3> list = new List<Vector3>(base.TerrainCurve.Count);
list.Add(this.ComputeFirstStripeVertex());
for (int i = 1; i < base.TerrainCurve.Count - 1; i++)
{
list.Add(this.ComputeStripeVertex(i));
}
list.Add(this.ComputeLastStripeVertex());
for (int j = 0; j < list.Count - 1; j++)
{
for (int k = j + 2; k < list.Count - 1; k++)
{
Vector2 v;
if (e2dUtils.SegmentsIntersect(list[j], list[j + 1], list[k], list[k + 1], out v))
{
for (int l = j + 1; l <= k; l++)
{
list[l] = v;
}
break;
}
}
}
return list;
}
private Vector3 ComputeFirstStripeVertex()
{
Vector2 position = base.TerrainCurve[0].position;
base.Boundary.ProjectStartPointToBoundary(ref position);
Vector3 result = position;
if (position != base.TerrainCurve[0].position)
{
Vector2 b = base.TerrainCurve[1].position - base.TerrainCurve[0].position;
float nodeStripeSize = this.GetNodeStripeSize(0);
Vector2 vector = new Vector2(b.y, -b.x);
Vector2 vector2 = nodeStripeSize * vector.normalized;
Vector2 b2 = position - base.TerrainCurve[0].position;
Vector2 zero;
if (!e2dUtils.HalfLineAndLineIntersect(Vector2.zero, b2, vector2, vector2 + b, out zero))
{
zero = Vector2.zero;
}
result = base.TerrainCurve[0].position + zero;
base.Boundary.EnsurePointIsInBoundary(ref result);
}
return result;
}
private Vector3 ComputeLastStripeVertex()
{
Vector2 position = base.TerrainCurve[base.TerrainCurve.Count - 1].position;
base.Boundary.ProjectEndPointToBoundary(ref position);
Vector3 result = position;
if (position != base.TerrainCurve[base.TerrainCurve.Count - 1].position)
{
Vector2 b = base.TerrainCurve[base.TerrainCurve.Count - 1].position - base.TerrainCurve[base.TerrainCurve.Count - 2].position;
float nodeStripeSize = this.GetNodeStripeSize(base.TerrainCurve.Count - 1);
Vector2 vector = new Vector2(b.y, -b.x);
Vector2 vector2 = nodeStripeSize * vector.normalized;
Vector2 b2 = position - base.TerrainCurve[base.TerrainCurve.Count - 1].position;
Vector2 zero;
if (!e2dUtils.HalfLineAndLineIntersect(Vector2.zero, b2, vector2, vector2 + b, out zero))
{
zero = Vector2.zero;
}
result = base.TerrainCurve[base.TerrainCurve.Count - 1].position + zero;
base.Boundary.EnsurePointIsInBoundary(ref result);
}
return result;
}
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 vector3 = new Vector2(vector.y, -vector.x);
Vector2 normalized = vector3.normalized;
Vector2 vector4 = new Vector2(vector2.y, -vector2.x);
Vector2 normalized2 = vector4.normalized;
Vector2 b = this.GetNodeStripeSize(nodeIndex) * (normalized + normalized2).normalized;
Vector3 result = base.TerrainCurve[nodeIndex].position + b;
base.Boundary.EnsurePointIsInBoundary(ref result);
return result;
}
private float GetNodeStripeSize(int nodeIndex)
{
e2dCurveTexture e2dCurveTexture = base.CurveTextures[base.TerrainCurve[nodeIndex].texture];
return e2dCurveTexture.size.y;
}
public void DestroyMesh()
{
base.EnsureMeshObjectsExist();
this.DestroyTemporaryAssets();
MeshFilter component = base.transform.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshFilter>();
if (component && component.sharedMesh != null)
{
UnityEngine.Object.DestroyImmediate(component.sharedMesh);
}
MeshRenderer component2 = base.transform.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshRenderer>();
if (component2 && component2.sharedMaterials != null)
{
foreach (Material obj in component2.sharedMaterials)
{
UnityEngine.Object.DestroyImmediate(obj);
}
}
}
public void RebuildMaterial()
{
base.EnsureMeshComponentsExist();
MeshRenderer component = base.transform.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshRenderer>();
Material[] array = component.sharedMaterials;
if (array != null)
{
foreach (Material obj in array)
{
UnityEngine.Object.DestroyImmediate(obj, true);
}
}
this.EnsureTexturesInited();
int materialsNeededCount = this.GetMaterialsNeededCount();
array = new Material[materialsNeededCount];
if (this.ControlTextures.Count != materialsNeededCount)
{
this.UpdateControlTextures();
}
int num = 0;
for (int j = 0; j < materialsNeededCount; j++)
{
array[j] = new Material(Shader.Find("e2d/Curve"));
array[j].SetFloat("_ControlSize", (float)this.ControlTextures[j].width);
array[j].SetFloat("_InvControlSize", 1f / (float)this.ControlTextures[j].width);
array[j].SetFloat("_InvControlSizeHalf", 0.5f / (float)this.ControlTextures[j].width);
array[j].SetTexture("_Control", this.ControlTextures[j]);
int k = 0;
while (k < e2dConstants.NUM_TEXTURES_PER_STRIPE_SHADER)
{
if (num >= base.CurveTextures.Count)
{
break;
}
array[j].SetTexture("_Splat" + k, base.CurveTextures[num].texture);
Vector4 value = new Vector4(1f / base.CurveTextures[num].size.x, base.CurveTextures[num].size.y, (float)((!base.CurveTextures[num].fixedAngle) ? 0 : 1), base.CurveTextures[num].fadeThreshold);
array[j].SetVector("_SplatParams" + k, value);
k++;
num++;
}
}
component.materials = array;
}
private void EnsureTexturesInited()
{
if (base.CurveTextures.Count == 0)
{
base.CurveTextures.Clear();
base.CurveTextures.Add(this.GetDefaultCurveTexture());
foreach (Texture obj in this.ControlTextures)
{
UnityEngine.Object.DestroyImmediate(obj, true);
}
this.ControlTextures.Clear();
this.ControlTextures.Add(this.CreateControlTexture(new Color(1f, 0f, 0f, 0f)));
}
}
public void UpdateControlTextures()
{
this.UpdateControlTextures(false);
}
public void UpdateControlTextures(bool forceRecreate)
{
while (this.ControlTextures.Count > this.GetMaterialsNeededCount())
{
UnityEngine.Object.DestroyImmediate(this.ControlTextures[this.ControlTextures.Count - 1], true);
this.ControlTextures.RemoveAt(this.ControlTextures.Count - 1);
}
while (this.ControlTextures.Count < this.GetMaterialsNeededCount())
{
this.ControlTextures.Add(this.CreateControlTexture(new Color(0f, 0f, 0f, 0f)));
}
for (int i = 0; i < this.ControlTextures.Count; i++)
{
if (forceRecreate || this.ControlTextures[i] == null || this.ControlTextures[i].width != this.GetControlTextureSize())
{
UnityEngine.Object.DestroyImmediate(this.ControlTextures[i], true);
this.ControlTextures[i] = this.CreateControlTexture(new Color(0f, 0f, 0f, 0f));
base.EnsureMeshComponentsExist();
MeshRenderer component = base.transform.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshRenderer>();
if (component.sharedMaterials != null && i == component.sharedMaterials.Length - 1 && component.sharedMaterials[i])
{
component.sharedMaterials[i].SetFloat("_ControlSize", (float)this.ControlTextures[i].width);
component.sharedMaterials[i].SetFloat("_InvControlSize", 1f / (float)this.ControlTextures[i].width);
component.sharedMaterials[i].SetFloat("_InvControlSizeHalf", 0.5f / (float)this.ControlTextures[i].width);
component.sharedMaterials[i].SetTexture("_Control", this.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;
}
}
}
this.ControlTextures[i].SetPixels(0, 0, array.Length, 1, array);
this.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 = this.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.Find(e2dConstants.CURVE_MESH_NAME).GetComponent<MeshRenderer>().sharedMaterial == null;
}
public void AppendCurveTexture()
{
base.Terrain.CurveTextures.Add(base.Terrain.CurveMesh.GetDefaultCurveTexture());
this.UpdateControlTextures();
}
public void RemoveCurveTexture(int index)
{
base.Terrain.CurveTextures.RemoveAt(index);
foreach (e2dCurveNode e2dCurveNode in base.TerrainCurve)
{
if (e2dCurveNode.texture == index)
{
e2dCurveNode.texture = 0;
}
else if (e2dCurveNode.texture > index)
{
e2dCurveNode.texture--;
}
}
this.UpdateControlTextures();
}
public void DestroyTemporaryAssets()
{
foreach (Texture2D texture2D in this.ControlTextures)
{
if (texture2D)
{
UnityEngine.Object.DestroyImmediate(texture2D, true);
}
}
this.ControlTextures.Clear();
}
public List<Texture2D> ControlTextures;
public List<Vector3> StripeVertices;
}