using System.Collections.Generic; using UnityEngine; namespace Mtree { public struct LeafPoint { public Vector3 position; public Vector3 direction; public float size; public Mesh[] meshes; public bool overrideNormals; public float distanceFromOrigin; private float length; private int uLoops; private float resolution; public bool procedural; private float gravityStrength; public LeafPoint(Vector3 pos, Vector3 dir, float size, Mesh[] m, bool overrideNorm, float distanceFromOrigin, float length = 1f, int uLoops = 2, float resolution = 1f, bool procedural = false, float gravityStrength = 1f) { position = pos; direction = dir; this.size = size; meshes = m; overrideNormals = overrideNorm; this.distanceFromOrigin = distanceFromOrigin; this.length = length; this.uLoops = uLoops; this.resolution = resolution; this.procedural = procedural; this.gravityStrength = gravityStrength; } public Mesh GetMesh(int lodLevel) { if (!procedural) { if (meshes != null && meshes.Length > 0) { return meshes[Mathf.Min(lodLevel, meshes.Length - 1)]; } return null; } return GrowLeaf(); } private Mesh GrowLeaf() { Vector3[] array = new Vector3[uLoops]; Vector2[] array2 = new Vector2[uLoops]; for (int i = 0; i < uLoops; i++) { float num = (float)i / (float)(uLoops - 1); float num2 = num - 0.5f; float y = 0f - Mathf.Pow(num - 0.5f, 2f); if (uLoops == 2) { y = 0f; } array[i] = new Vector3(num2 * 2f, y, 0f); array2[i] = new Vector2(num, 0f); } Queue queue = new Queue(); Quaternion quaternion = Quaternion.FromToRotation(Vector3.up, direction); quaternion = Quaternion.LookRotation(direction); Vector3[] array3 = array; foreach (Vector3 vector in array3) { queue.Enqueue(quaternion * vector * size + position); } Queue queue2 = new Queue(array2); Queue queue3 = new Queue(); Vector3 vector2 = position; Vector3 vector3 = direction.normalized; int num3 = Mathf.Max(1, (int)(length * resolution)); float num4 = length / (float)num3; for (int k = 0; k < num3; k++) { Vector3 vector4 = Vector3.Normalize(vector3 + Vector3.down * gravityStrength / resolution); Vector3 vector5 = vector2 + vector3 * num4; if ((Vector3.Angle(vector3, vector4) < 10f && k != num3 - 1) || vector5.y < 0f) { vector2 = vector5; vector3 = vector4; continue; } quaternion = Quaternion.FromToRotation(Vector3.up, Vector3.Slerp(vector3, vector4, 0.5f)); quaternion = Quaternion.LookRotation(vector3, Vector3.up); int count = queue.Count; for (int l = 0; l < uLoops; l++) { Vector3 item = quaternion * array[l] * size + vector5; queue.Enqueue(item); queue2.Enqueue(new Vector2((float)l / (float)(uLoops - 1), (float)(k + 1) / (float)num3)); if (l < uLoops - 1) { Utils.AddTriangle(queue3, count - uLoops + l, count + l, count - uLoops + 1 + l); Utils.AddTriangle(queue3, count + l, count + l + 1, count - uLoops + l + 1); } } vector2 = vector5; vector3 = vector4; } Mesh mesh = new Mesh(); mesh.vertices = queue.ToArray(); mesh.uv = queue2.ToArray(); mesh.triangles = queue3.ToArray(); mesh.RecalculateNormals(); return mesh; } } }