private void RecalculateNormals(Mesh mesh, float angle, int[] triangles, Vector3[] vertices, bool instant = false) { if (triangles == null) { if (meshInfoCache == null) { meshInfoCache = new Dictionary <Mesh, KeyValuePair <int[], Vector3[]> >(); } if (meshInfoCache.ContainsKey(mesh)) { triangles = meshInfoCache[mesh].Key; vertices = meshInfoCache[mesh].Value; } else { triangles = mesh.GetTriangles(0); vertices = mesh.vertices; meshInfoCache.Add(mesh, new KeyValuePair <int[], Vector3[]>(triangles, vertices)); } } var triNormals = AllocatedArray <Vector3> .Get(triangles.Length / 3); var normals = AllocatedArray <Vector3> .Get(vertices.Length); angle = angle * Mathf.Deg2Rad; var dictionary = PooledDictionary <Vector3, VertexEntry> .Get(vertices.Length, VectorComparer); //Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; Vector3 normal = Vector3.Cross(p1, p2).normalized; int triIndex = i / 3; triNormals[triIndex] = normal; VertexEntry entry; //VertexKey key; //For each of the three points of the triangle // > Add this triangle as part of the triangles they're connected to. if (!dictionary.TryGetValue(vertices[i1], out entry)) { entry = GenericObjectPool <VertexEntry> .Get(); entry.PopulateArrays(); dictionary.Add(vertices[i1], entry); } entry.Add(i1, triIndex); if (!dictionary.TryGetValue(vertices[i2], out entry)) { entry = GenericObjectPool <VertexEntry> .Get(); entry.PopulateArrays(); dictionary.Add(vertices[i2], entry); } entry.Add(i2, triIndex); if (!dictionary.TryGetValue(vertices[i3], out entry)) { entry = GenericObjectPool <VertexEntry> .Get(); entry.PopulateArrays(); dictionary.Add(vertices[i3], entry); } entry.Add(i3, triIndex); } foreach (var kvp in dictionary) { var value = kvp.Value; for (var i = 0; i < value.Count; ++i) { var sum = new Vector3(); for (var j = 0; j < value.Count; ++j) { if (value.VertexIndex[i] == value.VertexIndex[j]) { sum += triNormals[value.TriangleIndex[j]]; } else { float dot = Vector3.Dot( triNormals[value.TriangleIndex[i]], triNormals[value.TriangleIndex[j]]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); if (acos <= angle) { sum += triNormals[value.TriangleIndex[j]]; } } } normals[value.VertexIndex[i]] = sum.normalized; } value.Clear(); GenericObjectPool <VertexEntry> .Return(value); } dictionary.ReturnToPool(); if (instant == false) { if (mainThreadActions == null) { mainThreadActions = new Queue <System.Action>(); } mainThreadActions.Enqueue(() => { if (mesh) { mesh.normals = normals; } AllocatedArray <Vector3> .Return(normals, false); }); } else { mesh.normals = normals; AllocatedArray <Vector3> .Return(normals, false); } }