Beispiel #1
0
        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);
        }
Beispiel #2
0
        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;
        }