/// <summary> /// Addds one face to our render buffer /// </summary> /// <param name="materialID">ID of material to use when building the mesh</param> /// <param name="verts"> An array of 4 vertices forming the face</param> /// <param name="colors">An array of 4 colors</param> /// <param name="uvs">An array of 4 UV coordinates</param> /// <param name="backFace">If false, vertices are added clock-wise</param> public void AddFace(int materialID, Vector3[] verts, Color32[] colors, Vector4[] uvs, bool backFace) { Assert.IsTrue(verts.Length == 4); List <RenderGeometryBuffer> holder = Buffers[materialID]; RenderGeometryBuffer buffer = holder[holder.Count - 1]; // If there are too many vertices we need to create a new separate buffer for them if (buffer.vertices.Count + 4 > 65000) { buffer = new RenderGeometryBuffer { uV1s = new List <Vector4>(), colors = new List <Color32>() }; holder.Add(buffer); } // Add vertices int initialVertexCount = buffer.vertices.Count; buffer.vertices.AddRange(verts); // Add UVs PrepareUVs(ref buffer.uV1s, buffer.vertices, initialVertexCount); buffer.uV1s.AddRange(uvs); // Add colors PrepareColors(ref buffer.colors, buffer.vertices, initialVertexCount); buffer.colors.AddRange(colors); // Add indices buffer.AddIndices(buffer.vertices.Count, backFace); }
/// <summary> /// Finalize the draw calls /// </summary> public void Commit(Vector3 position, Quaternion rotation, ref Bounds bounds #if DEBUG , string debugName = null #endif ) { ReleaseOldData(); for (int j = 0; j < Buffers.Length; j++) { List <RenderGeometryBuffer> holder = Buffers[j]; Material material = (materials == null || materials.Length < 1) ? null : materials[j]; for (int i = 0; i < holder.Count; i++) { RenderGeometryBuffer buffer = holder[i]; // No data means there's no mesh to build if (buffer.IsEmpty) { continue; } GameObject go = GameObjectProvider.PopObject(prefabName); Assert.IsTrue(go != null); if (go != null) { #if DEBUG go.name = string.Format(debugName, "_", i.ToString()); #endif Mesh mesh = Globals.MemPools.meshPool.Pop(); Assert.IsTrue(mesh.vertices.Length <= 0); buffer.SetupMesh(mesh, false); mesh.bounds = bounds; MeshFilter filter = go.GetComponent <MeshFilter>(); filter.sharedMesh = null; filter.sharedMesh = mesh; Transform t = filter.transform; t.position = position; t.rotation = rotation; Renderer renderer = go.GetComponent <Renderer>(); renderer.enabled = true; renderer.sharedMaterial = material; objects.Add(go); } buffer.Clear(); } } }
public void Reset() { // Buffers need to be reallocated. Otherwise, more and more memory would be consumed by them. This is // because internal arrays grow in capacity and we can't simply release their memory by calling Clear(). // Objects and renderers are fine, because there's usually only 1 of them. In some extreme cases they // may grow more but only by 1 or 2 (and only if Env.ChunkPow>5). for (int i = 0; i < Buffers.Length; i++) { List <RenderGeometryBuffer> geometryBuffer = Buffers[i]; for (int j = 0; j < geometryBuffer.Count; j++) { if (geometryBuffer[j].WasUsed) { geometryBuffer[j] = new RenderGeometryBuffer(); } } } ReleaseOldData(); enabled = false; }
/// <summary> /// Addds one face to our render buffer /// </summary> /// <param name="materialID">ID of material to use when building the mesh</param> /// <param name="tris">Triangles to be processed</param> /// <param name="verts">Vertices to be processed</param> /// <param name="colors">Colors to be processed</param> /// <param name="uvs">UVs to be processed</param> /// <param name="texture">Texture coordinates</param> /// <param name="offset">Offset to apply to vertices</param> public void AddMeshData(int materialID, int[] tris, Vector3[] verts, Color32[] colors, Vector4[] uvs, ref Rect texture, Vector3 offset) { // Each face consists of 6 triangles and 4 faces Assert.IsTrue(((verts.Length * 3) >> 1) == tris.Length); Assert.IsTrue((verts.Length & 3) == 0); List <RenderGeometryBuffer> holder = Buffers[materialID]; RenderGeometryBuffer buffer = holder[holder.Count - 1]; int startOffset = 0; int leftToProcess = verts.Length; while (leftToProcess > 0) { int left = System.Math.Min(leftToProcess, 65000); int leftInBuffer = 65000 - buffer.vertices.Count; if (leftInBuffer <= 0) { buffer = new RenderGeometryBuffer { uV1s = new List <Vector4>(), colors = new List <Color32>() }; buffer.triangles.Capacity = left; buffer.vertices.Capacity = left; buffer.uV1s.Capacity = left; buffer.colors.Capacity = left; holder.Add(buffer); } else { left = System.Math.Min(left, leftInBuffer); } int max = startOffset + left; int maxTris = (max * 3) >> 1; int offsetTri = (startOffset * 3) >> 1; // Add vertices int initialVertexCount = buffer.vertices.Count; for (int i = startOffset; i < max; i++) { buffer.vertices.Add(verts[i] + offset); } // Add UVs PrepareUVs(ref buffer.uV1s, buffer.vertices, initialVertexCount); for (int i = startOffset; i < max; i++) { // Adjust UV coordinates according to provided texture atlas buffer.uV1s.Add(new Vector4((uvs[i].x * texture.width) + texture.x, (uvs[i].y * texture.height) + texture.y)); } // Add colors PrepareColors(ref buffer.colors, buffer.vertices, initialVertexCount); for (int i = startOffset; i < max; i++) { buffer.colors.Add(colors[i]); } // Add triangles for (int i = offsetTri; i < maxTris; i++) { buffer.triangles.Add(tris[i] + initialVertexCount); } leftToProcess -= left; startOffset += left; } }