/// <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 StartCrossfade(SnapshotMeshFrameData fromFrame, SnapshotMeshFrameData toFrame) { Reset(false); isReset = false; this.fromFrame = fromFrame; this.toFrame = toFrame; int vertexLength = fromFrame.verts.Length; if (positionJobs == null) { positionJobs = AllocatedArray <LerpVector3Job> .Get(framesNeeded); } if (boundsJobs == null) { boundsJobs = AllocatedArray <CalculateBoundsJob> .Get(framesNeeded); } if (positionJobHandles == null) { positionJobHandles = AllocatedArray <JobHandle> .Get(framesNeeded); } if (boundsJobHandles == null) { boundsJobHandles = AllocatedArray <JobHandle> .Get(framesNeeded); } if (output == null) { output = AllocatedArray <NativeArray <Vector3> > .Get(framesNeeded); } from = new NativeArray <Vector3>(vertexLength, Allocator.Persistent); to = new NativeArray <Vector3>(vertexLength, Allocator.Persistent); from.CopyFrom(fromFrame.verts); to.CopyFrom(toFrame.verts); for (int i = 0; i < framesNeeded; i++) { output[i] = new NativeArray <Vector3>(vertexLength, Allocator.Persistent); float delta = i / (float)framesNeeded; var lerpJob = new LerpVector3Job() { from = from, to = to, output = output[i], delta = delta }; positionJobs[i] = lerpJob; positionJobHandles[i] = lerpJob.Schedule(vertexLength, 64); var boundsJob = new CalculateBoundsJob() { positions = output[i] }; boundsJobs[i] = boundsJob; boundsJobHandles[i] = boundsJob.Schedule(positionJobHandles[i]); } }
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)); } }
public void PopulateArrays() { TriangleIndex = AllocatedArray <int> .Get(_reserved); VertexIndex = AllocatedArray <int> .Get(_reserved); }
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); } }