/// <summary> /// Populates the crossfade pool with the set amount of meshes /// </summary> /// <param name="count">Amount to fill the pool with</param> public override void PrepopulateCrossfadePool(int count) { Stack <Mesh> pool = null; lock (_crossFadePool) { if (crossFadePoolIndex > -1) { pool = _crossFadePool[crossFadePoolIndex]; count = pool.Count - count; if (count <= 0) { return; } } } Mesh[] meshes = AllocatedArray <Mesh> .Get(count); for (int i = 0; i < count; i++) { meshes[i] = GetCrossfadeFromPool(); } for (int i = 0; i < count; i++) { crossfadeMesh = meshes[i]; ReturnCrossfadeToPool(true); meshes[i] = null; } AllocatedArray <Mesh> .Return(meshes); }
public void Clear() { _count = 0; AllocatedArray <int> .Return(TriangleIndex, false); AllocatedArray <int> .Return(VertexIndex, false); TriangleIndex = null; VertexIndex = null; }
protected override bool DisplayFrame(int previousFrame) { if (currentFrame == previousFrame) { return(base.DisplayFrame(previousFrame)); } if (currentCrossFade.isFading) { if (currentCrossFade.currentFrame >= currentCrossFade.framesNeeded) { ReturnCrossfadeToPool(false); } else { // complete any jobs not done for the current frame currentCrossFade.positionJobHandles[currentCrossFade.currentFrame].Complete(); currentCrossFade.boundsJobHandles[currentCrossFade.currentFrame].Complete(); if (crossfadeMesh == null) { crossfadeMesh = GetCrossfadeFromPool(); } // copy positions from job var verts = AllocatedArray <Vector3> .Get(currentAnimation.vertexCount); currentCrossFade.positionJobs[currentCrossFade.currentFrame].output.CopyTo(verts); crossfadeMesh.vertices = verts; AllocatedArray.Return(verts); // copy bounds from job crossfadeMesh.bounds = currentCrossFade.boundsJobs[currentCrossFade.currentFrame].bounds; // recalculate normals if (recalculateCrossfadeNormals) { crossfadeMesh.RecalculateNormals(); } // set mesh meshFilter.sharedMesh = crossfadeMesh; currentCrossFade.currentFrame++; } return(base.DisplayFrame(previousFrame)); } else { return(base.DisplayFrame(previousFrame)); } }
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); } }
public void ReturnFrame(bool destroying) { try { if (positionJobHandles != null) { for (int i = 0; i < positionJobHandles.Length; i++) { if (destroying || currentFrame <= i) { positionJobHandles[i].Complete(); } } AllocatedArray.Return(positionJobHandles, true); positionJobHandles = null; } if (boundsJobHandles != null) { for (int i = 0; i < boundsJobHandles.Length; i++) { if (destroying || currentFrame <= i) { boundsJobHandles[i].Complete(); } } AllocatedArray.Return(boundsJobHandles, true); boundsJobHandles = null; } if (positionJobs != null) { AllocatedArray.Return(positionJobs, true); positionJobs = null; } if (boundsJobs != null) { AllocatedArray.Return(boundsJobs, true); boundsJobs = null; } if (output != null) { if (from.IsCreated) { from.Dispose(); } if (to.IsCreated) { to.Dispose(); } for (int i = 0; i < output.Length; i++) { if (output[i].IsCreated) { output[i].Dispose(); } } AllocatedArray.Return(output); output = null; } } catch (System.Exception ex) { Debug.LogException(ex); } }