/// <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, Vector2[] uvs, bool backFace) { Assert.IsTrue(verts.Length == 4); var holder = m_buffers[materialID]; var 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 <Vector2>(), 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); }
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 < m_buffers.Length; i++) { var geometryBuffer = m_buffers[i]; for (int j = 0; j < geometryBuffer.Count; j++) { if (geometryBuffer[j].WasUsed) { geometryBuffer[j] = new RenderGeometryBuffer(); } } } ReleaseOldData(); m_enabled = false; }
private bool SetUpMesh(World world, string meshLocation, Vector3 positionOffset) { FileStream fs = null; try { string fullPath = Directories.ResourcesFolder + "/" + meshLocation + ".vox"; fs = new FileStream(fullPath, FileMode.Open); using (BinaryReader br = new BinaryReader(fs)) { // Load the magica vox model var data = MagicaVox.FromMagica(br); if (data == null) { return(false); } MagicaVox.MagicaVoxelChunk mvchunk = data.chunk; // Determine the biggest side int size = mvchunk.sizeX; if (mvchunk.sizeY > size) { size = mvchunk.sizeY; } if (mvchunk.sizeZ > size) { size = mvchunk.sizeZ; } // Determine the necessary size size += Env.ChunkPadding2; int pow = 1 + (int)Math.Log(size, 2); size = (1 << pow) - Env.ChunkPadding2; // Create a temporary chunk object Chunk chunk = new Chunk(size); chunk.Init(world, Vector3Int.zero); ChunkBlocks blocks = chunk.blocks; // Convert the model's data to our internal system for (int y = 0; y < mvchunk.sizeY; y++) { for (int z = 0; z < mvchunk.sizeZ; z++) { for (int x = 0; x < mvchunk.sizeX; x++) { int index = Helpers.GetChunkIndex1DFrom3D(x, y, z, pow); int i = Helpers.GetIndex1DFrom3D(x, y, z, mvchunk.sizeX, mvchunk.sizeZ); // TODO: Implement support for colors blocks.SetInner( index, data.chunk.data[i] == 0 ? BlockProvider.AirBlock : new BlockData(type, true)//new BlockData((ushort)i, true) ); } } } Block block = world.blockProvider.BlockTypes[type]; block.Custom = false; m_geomBuffer = new RenderGeometryBuffer() { Colors = new List <Color32>() }; { // Build the mesh CubeMeshBuilder meshBuilder = new CubeMeshBuilder(m_scale, size) { SideMask = 0, Type = type, Palette = data.palette }; meshBuilder.Build(chunk, out chunk.minBounds, out chunk.maxBounds); // Convert lists to arrays verts = m_geomBuffer.Vertices.ToArray(); colors = m_geomBuffer.Colors.ToArray(); tris = m_geomBuffer.Triangles.ToArray(); } m_geomBuffer = null; block.Custom = true; fs = null; } } catch (Exception ex) { Debug.LogException(ex); return(false); } finally { if (fs != null) { fs.Dispose(); } } return(true); }
/// <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, Vector2[] 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); var holder = m_buffers[materialID]; var buffer = holder[holder.Count - 1]; int startOffset = 0; int leftToProcess = verts.Length; while (leftToProcess > 0) { int left = Math.Min(leftToProcess, 65000); int leftInBuffer = 65000 - buffer.Vertices.Count; if (leftInBuffer <= 0) { buffer = new RenderGeometryBuffer { UV1s = new List <Vector2>(), 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 = 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 Vector2( (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; } }
/// <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="offset">Offset to apply to verts</param> public void AddMeshData(int materialID, int[] tris, Vector3[] verts, Color32[] colors, 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); var holder = Buffers[materialID]; var buffer = holder[holder.Count - 1]; int startOffset = 0; int leftToProcess = verts.Length; while (leftToProcess > 0) { int left = Math.Min(leftToProcess, 65000); int leftInBuffer = 65000 - buffer.Vertices.Count; if (leftInBuffer <= 0) { buffer = new RenderGeometryBuffer { Colors = new List <Color32>() }; buffer.Triangles.Capacity = left; buffer.Vertices.Capacity = left; buffer.Colors.Capacity = left; holder.Add(buffer); } else { left = 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 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; } }