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); } }
/// <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); }
/// <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); }