public void AddMeshData(int[] tris, VertexDataFixed[] verts, Rect texture, Vector3 offset)
        {
            GeometryBuffer buffer = m_buffers[m_buffers.Count - 1];

            int initialVertCount = buffer.Vertices.Count;

            for (int i = 0; i < verts.Length; i++)
            {
                // If there are too many vertices we need to create a new separate buffer for them
                if (buffer.Vertices.Count + 1 > 65000)
                {
                    buffer = new GeometryBuffer();
                    m_buffers.Add(buffer);
                }

                VertexDataFixed v = new VertexDataFixed()
                {
                    Color   = verts[i].Color,
                    Normal  = verts[i].Normal,
                    Tangent = verts[i].Tangent,
                    // Adjust UV coordinates based on provided texture atlas
                    UV = new Vector2(
                        (verts[i].UV.x * texture.width) + texture.x,
                        (verts[i].UV.y * texture.height) + texture.y
                        ),
                    Vertex = verts[i].Vertex + offset
                };
                buffer.AddVertex(ref v);
            }

            for (int i = 0; i < tris.Length; i++)
            {
                buffer.AddIndex(tris[i] + initialVertCount);
            }
        }
示例#2
0
        /// <summary>
        ///     Copy collider geometry data to a Unity mesh
        /// </summary>
        public static void BuildColliderMesh(Mesh mesh, GeometryBuffer buffer)
        {
            int size = buffer.Vertices.Count;

            // Avoid allocations by retrieving buffers from the pool
            Vector3[] vertices = Globals.MemPools.PopVector3Array(size);

            // Fill buffers with data
            for (int i = 0; i < size; i++)
            {
                VertexDataFixed vertexData = buffer.Vertices[i];
                vertices[i] = vertexData.Vertex;
            }

            // Due to the way the memory pools work we might have received more
            // data than necessary. This little overhead is well worth it, though.
            // Fill unused data with "zeroes"
            for (int i = size; i < vertices.Length; i++)
            {
                vertices[i] = Vector3.zero;
            }

            // Prepare mesh
            mesh.vertices = vertices;
            mesh.SetTriangles(buffer.Triangles, 0);

            // Return memory back to pool
            Globals.MemPools.PushVector3Array(vertices);
        }
示例#3
0
        /// <summary>
        ///     Copy render geometry data to a Unity mesh
        /// </summary>
        public static void BuildGeometryMesh(Mesh mesh, GeometryBuffer buffer)
        {
            int size = buffer.Vertices.Count;

            // Avoid allocations by retrieving buffers from the pool
            Vector3[] vertices = Globals.MemPools.PopVector3Array(size);
            Vector2[] uvs      = Globals.MemPools.PopVector2Array(size);
            Color32[] colors   = Globals.MemPools.PopColor32Array(size);
            Vector3[] normals  = Globals.MemPools.PopVector3Array(size);
            Vector4[] tangents = Globals.MemPools.PopVector4Array(size);

            // Fill buffers with data
            for (int i = 0; i < size; i++)
            {
                VertexDataFixed vertexData = buffer.Vertices[i];
                vertices[i] = vertexData.Vertex;
                uvs[i]      = vertexData.UV;
                colors[i]   = vertexData.Color;
                normals[i]  = vertexData.Normal;
                tangents[i] = vertexData.Tangent;
            }

            // Due to the way the memory pools work we might have received more
            // data than necessary. This little overhead is well worth it, though.
            // Fill unused data with "zeroes"
            for (int i = size; i < vertices.Length; i++)
            {
                vertices[i] = Vector3.zero;
                uvs[i]      = Vector2.zero;
                colors[i]   = Color.clear;
                normals[i]  = Vector3.zero;
                tangents[i] = Vector4.zero;
            }

            // Prepare mesh
            mesh.vertices = vertices;
            mesh.uv       = uvs;
            mesh.colors32 = colors;
            mesh.normals  = normals;
            mesh.tangents = tangents;
            mesh.SetTriangles(buffer.Triangles, 0);
            mesh.RecalculateNormals();
            mesh.Optimize();

            // Return memory back to pool
            Globals.MemPools.PushVector3Array(vertices);
            Globals.MemPools.PushVector2Array(uvs);
            Globals.MemPools.PushColor32Array(colors);
            Globals.MemPools.PushVector3Array(normals);
            Globals.MemPools.PushVector4Array(tangents);
        }
    protected static void SetUpMesh(string meshLocation, Vector3 positionOffset, out int[] trisOut, out VertexDataFixed[] vertsOut)
    {
        GameObject meshGO = (GameObject)Resources.Load(meshLocation);

        int vertexCnt   = 0;
        int triangleCnt = 0;

        for (int GOIndex = 0; GOIndex < meshGO.transform.childCount; GOIndex++)
        {
            Mesh mesh = meshGO.transform.GetChild(GOIndex).GetComponent <MeshFilter>().sharedMesh;

            vertexCnt   += mesh.vertices.Length;
            triangleCnt += mesh.triangles.Length;
        }

        trisOut  = new int[triangleCnt];
        vertsOut = new VertexDataFixed[vertexCnt];

        int ti = 0, vi = 0;

        for (int GOIndex = 0; GOIndex < meshGO.transform.childCount; GOIndex++)
        {
            Mesh mesh = meshGO.transform.GetChild(GOIndex).GetComponent <MeshFilter>().sharedMesh;

            for (int i = 0; i < mesh.vertices.Length; i++, vi++)
            {
                vertsOut[vi] = new VertexDataFixed
                {
                    Vertex = mesh.vertices[i] + positionOffset,
                    UV     = mesh.uv.Length != 0 ? mesh.uv[i] : new Vector2(),
                    //Coloring of blocks is not yet implemented so just pass in full brightness
                    Color = new Color32(1, 1, 1, 1)
                };
            }

            for (int i = 0; i < mesh.triangles.Length; i++, ti++)
            {
                trisOut[ti] = mesh.triangles[i];
            }
        }
    }
        public static void GenerateTangents(this GeometryBuffer buffer, LocalPools pools)
        {
            var vertices  = buffer.Vertices;
            var triangles = buffer.Triangles;

            var tan1 = pools.PopVector3Array(vertices.Count);
            var tan2 = pools.PopVector3Array(vertices.Count);

            for (int t = 0; t < triangles.Count; t += 3)
            {
                int i1 = triangles[t + 0];
                int i2 = triangles[t + 1];
                int i3 = triangles[t + 2];

                VertexDataFixed vd1 = vertices[i1];
                VertexDataFixed vd2 = vertices[i2];
                VertexDataFixed vd3 = vertices[i3];

                Vector3 v1 = vd1.Vertex;
                Vector3 v2 = vd2.Vertex;
                Vector3 v3 = vd3.Vertex;

                Vector2 w1 = vd1.UV;
                Vector2 w2 = vd2.UV;
                Vector2 w3 = vd3.UV;

                float x1 = v2.x - v1.x;
                float y1 = v2.y - v1.y;
                float z1 = v2.z - v1.z;

                float x2 = v3.x - v1.x;
                float y2 = v3.y - v1.y;
                float z2 = v3.z - v1.z;

                float s1 = w2.x - w1.x;
                float s2 = w3.x - w1.x;

                float t1 = w2.y - w1.y;
                float t2 = w3.y - w1.y;

                // Avoid division by zero
                float div = s1 * t2 - s2 * t1;
                float r   = (Mathf.Abs(div) > Mathf.Epsilon) ? (1f / div) : 0f;

                Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
                Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

                tan1[i1] += sdir;
                tan1[i2] += sdir;
                tan1[i3] += sdir;

                tan2[i1] += tdir;
                tan2[i2] += tdir;
                tan2[i3] += tdir;
            }

            for (int v = 0; v < vertices.Count; ++v)
            {
                VertexDataFixed vd = vertices[v];

                Vector3 n = vd.Normal;
                Vector3 t = tan1[v];

                //Vector3 tmp = (t - n*Vector3.Dot(n, t)).normalized;
                //tangents[v] = new Vector4(tmp.x, tmp.y, tmp.z);
                Vector3.OrthoNormalize(ref n, ref t);

                vd.Tangent = new Vector4(
                    t.x, t.y, t.z,
                    (Vector3.Dot(Vector3.Cross(n, t), tan2[v]) < 0.0f) ? -1.0f : 1.0f
                    );

                tan1[v] = Vector3.zero;
                tan2[v] = Vector3.zero;
            }

            pools.PushVector3Array(tan1);
            pools.PushVector3Array(tan2);
        }
 public static void AddVertex(this GeometryBuffer target, ref VertexDataFixed vertex)
 {
     target.Vertices.Add(vertex);
 }