static ComputeBuffer GenerateMeshData(MeshIndex meshIndex) { var mesh = meshIndex.Mesh; var uvChannel = meshIndex.UvChannel; //Build mesh data structure mesh.GetVertices(s_verts); mesh.GetNormals(s_normals); mesh.GetTriangles(s_triangles, 0); int count = s_triangles.Count / 3; uvChannel = Mathf.Clamp(uvChannel, 0, 4); mesh.GetUVs(uvChannel, s_uvs); //TODO: Reuse face somehow? ComputeBuffer buffer; if (!s_meshStore.TryGetValue(meshIndex, out buffer)) { buffer = new ComputeBuffer(count, ParticleComponent.SizeOf <Face>()); s_meshStore[meshIndex] = buffer; } else { if (buffer == null || buffer.count != count) { if (buffer != null) { buffer.Dispose(); } buffer = new ComputeBuffer(count, ParticleComponent.SizeOf <Face>()); s_meshStore[meshIndex] = buffer; } } while (s_faces.Length < buffer.count) { Array.Resize(ref s_faces, s_faces.Length * 2); } float totalArea = 0.0f; //TODO: Can't we parralise this easily? for (int i = 0; i < count; ++i) { int i3 = i * 3; int t0 = s_triangles[i3 + 0]; int t1 = s_triangles[i3 + 1]; int t2 = s_triangles[i3 + 2]; s_faces[i] = new Face { a = s_verts[t0], b = s_verts[t1], c = s_verts[t2], na = s_normals[t0], nb = s_normals[t1], nc = s_normals[t2], uva = s_uvs[t0], uvb = s_uvs[t1], uvc = s_uvs[t2] }; //Calculate area of triangle manually. //Equivalent to 0.5 * | (a - b) x (a - c) | float x1 = s_verts[t0].x - s_verts[t1].x; float x2 = s_verts[t0].y - s_verts[t1].y; float x3 = s_verts[t0].z - s_verts[t1].z; float y1 = s_verts[t0].x - s_verts[t2].x; float y2 = s_verts[t0].y - s_verts[t2].y; float y3 = s_verts[t0].z - s_verts[t2].z; float r1 = x2 * y3 - x3 * y2; float r2 = x3 * y1 - x1 * y3; float r3 = x1 * y2 - x2 * y1; float area = 0.5f * Mathf.Sqrt(r1 * r1 + r2 * r2 + r3 * r3); s_faces[i].cweight = area; totalArea += area; } float cumulative = 0; for (int i = 0; i < count; ++i) { cumulative += s_faces[i].cweight / totalArea; s_faces[i].cweight = cumulative; } buffer.SetData(s_faces, 0, 0, count); return(buffer); }
void GenerateMeshData() { //Data already cached! if (TCParticleGlobalRender.MeshStore.ContainsKey(emitMesh)) { return; } //Build mesh data structure Vector3[] vertices = emitMesh.vertices; Vector3[] normals = emitMesh.normals; int[] triangles = emitMesh.triangles; int count = triangles.Length / 3; List <Vector2> uvs = new List <Vector2>(); uvChannel = Mathf.Clamp(uvChannel, 0, 4); emitMesh.GetUVs(uvChannel, uvs); var faces = new Face[count]; for (int i = 0; i < count; ++i) { int t0 = triangles[i * 3 + 0]; int t1 = triangles[i * 3 + 1]; int t2 = triangles[i * 3 + 2]; faces[i] = new Face { a = vertices[t0], b = vertices[t1], c = vertices[t2], na = normals[t0], nb = normals[t1], nc = normals[t2], uva = uvs[t0], uvb = uvs[t1], uvc = uvs[t2] }; //Do we accumulate area for normlisation? if (normalizeArea) { float area = Vector3.Cross(faces[i].a - faces[i].b, faces[i].c - faces[i].a).magnitude / 2.0f; faces[i].cweight = area; m_totalArea += area; } else { faces[i].cweight = 0.0f; } } if (normalizeArea) { float cumulative = 0; for (int i = 0; i < count; ++i) { cumulative += faces[i].cweight / m_totalArea; faces[i].cweight = cumulative; } } var buffer = new ComputeBuffer(count, ParticleComponent.SizeOf <Face>()); buffer.SetData(faces); TCParticleGlobalRender.MeshStore[emitMesh] = buffer; }