public override bool Equals(object obj) { if (!(obj is ChunkVertex)) { return(false); } ChunkVertex vertex = (ChunkVertex)obj; return(Position.Equals(vertex.Position)); }
public static void GenerateMesh(Common.VoxelEngine.Spaceship.SmallShip.Chunk chunk, ChunkMesh chunkMesh) { ChunkVertex[] vertices = new ChunkVertex[SmallShipComponent.CHUNK_SIZE_CUBE * 6 * 4]; uint[] indices = new uint[SmallShipComponent.CHUNK_SIZE_CUBE * 6 * 6]; uint vertexCount = 0; int indexCount = 0; #if _DEBUG_CHUNKS Stopwatch generationTimer = Stopwatch.StartNew(); #endif // _DEBUG_CHUNKS int shift = 0; int i = 0; uint[] pos = new uint[3]; int index = 0; int A, B; for (pos[2] = 0; pos[2] < SmallShipComponent.CHUNK_SIZE; pos[2]++) { for (pos[1] = 0; pos[1] < SmallShipComponent.CHUNK_SIZE; pos[1]++) { for (pos[0] = 0; pos[0] < SmallShipComponent.CHUNK_SIZE; pos[0]++) { shift = 0; A = chunk.blocks[index]; for (i = 0; i < 3; i++) { if (pos[i] == SmallShipComponent.CHUNK_SIZE_MASK) { B = 0; } else { B = chunk.blocks[index + (1 << shift)]; } if (A > 0 == B > 0) { continue; } // There is a face, render it if (B == 0) { // Render this blocks face } else { // Render the adjacent block's face } shift += SmallShipComponent.LOG_CHUNK_SIZE; } index++; } } } #if _DEBUG_CHUNKS generationTimer.Stop(); Debug.Log($"ShipChunk Meshing Speed: {generationTimer.Elapsed.TotalMilliseconds}"); #endif // _DEBUG_CHUNKS chunkMesh.SetData(vertices, indices); }
public void UpdateData() { int width = m_distanceField.Width; int height = m_distanceField.Height; int depth = m_distanceField.Depth; int halfWidth = width / 2; int halfHeight = height / 2; int halfDepth = depth / 2; DistanceField <Voxel> .Cell[] voxels = new DistanceField <Voxel> .Cell[8]; DistanceField <Voxel> .Cell[] cells = m_distanceField.Cells; List <ChunkVertex> dirtyVerts = new List <ChunkVertex>(); for (int x = 0; x < m_distanceField.Width - 1; ++x) { int x1 = x + 1; for (int y = 0; y < m_distanceField.Height - 1; ++y) { int y1 = y + 1; for (int z = 0; z < m_distanceField.Depth - 1; ++z) { int z1 = z + 1; voxels[0] = cells[(z * width * height) + (y * width) + x]; voxels[1] = cells[(z * width * height) + (y * width) + x1]; voxels[2] = cells[(z1 * width * height) + (y * width) + x1]; voxels[3] = cells[(z1 * width * height) + (y * width) + x]; voxels[4] = cells[(z * width * height) + (y1 * width) + x]; voxels[5] = cells[(z * width * height) + (y1 * width) + x1]; voxels[6] = cells[(z1 * width * height) + (y1 * width) + x1]; voxels[7] = cells[(z1 * width * height) + (y1 * width) + x]; MarchingCubes.Polygonise(m_distanceField, voxels, x - halfWidth, y - halfHeight, z - halfDepth, 0.0f, dirtyVerts); } } } int count = dirtyVerts.Count; List <uint> indicies = new List <uint>(); List <ChunkVertex> vertices = new List <ChunkVertex>(); Dictionary <ChunkVertex, uint> values = new Dictionary <ChunkVertex, uint>(); for (int i = 0; i < count; i += 3) { ChunkVertex vertA = dirtyVerts[i]; ChunkVertex vertB = dirtyVerts[i + 1]; ChunkVertex vertC = dirtyVerts[i + 2]; Vector3 v1 = vertC.Position.Xyz - vertA.Position.Xyz; Vector3 v2 = vertB.Position.Xyz - vertA.Position.Xyz; Vector3 normal = Vector3.Cross(v2, v1); uint index; if (values.TryGetValue(vertA, out index)) { ChunkVertex vertex = vertices[(int)index]; vertex.Normal += normal; vertices[(int)index] = vertex; indicies.Add(index); } else { index = (uint)vertices.Count; vertA.Normal = normal; indicies.Add(index); values.Add(vertA, index); vertices.Add(vertA); } if (values.TryGetValue(vertB, out index)) { ChunkVertex vertex = vertices[(int)index]; vertex.Normal += normal; vertices[(int)index] = vertex; indicies.Add(index); } else { index = (uint)vertices.Count; vertB.Normal = normal; indicies.Add(index); values.Add(vertB, index); vertices.Add(vertB); } if (values.TryGetValue(vertC, out index)) { ChunkVertex vertex = vertices[(int)index]; vertex.Normal += normal; vertices[(int)index] = vertex; indicies.Add(index); } else { index = (uint)vertices.Count; vertC.Normal = normal; indicies.Add(index); values.Add(vertC, index); vertices.Add(vertC); } } float maxRadius = 0.0f; int vertexCount = vertices.Count; for (int i = 0; i < vertexCount; ++i) { ChunkVertex vert = vertices[i]; vert.Normal = vert.Normal.Normalized(); vertices[i] = vert; float distSqr = vert.Position.LengthSquared; if (distSqr > maxRadius) { maxRadius = distSqr; } } float radius = (float)Math.Sqrt(maxRadius); ModelVertexInfo[] vertexInfoCollection = new ModelVertexInfo[3]; vertexInfoCollection[0].Offset = Marshal.OffsetOf <ChunkVertex>("Position"); vertexInfoCollection[0].Count = 4; vertexInfoCollection[0].Type = e_FieldType.Float; vertexInfoCollection[0].Normalize = false; vertexInfoCollection[1].Offset = Marshal.OffsetOf <ChunkVertex>("Normal"); vertexInfoCollection[1].Count = 3; vertexInfoCollection[1].Type = e_FieldType.Float; vertexInfoCollection[1].Normalize = false; vertexInfoCollection[2].Offset = Marshal.OffsetOf <ChunkVertex>("Color"); vertexInfoCollection[2].Count = 4; vertexInfoCollection[2].Type = e_FieldType.UnsignedByte; vertexInfoCollection[2].Normalize = true; m_model.SetModelData <ChunkVertex>(vertices.ToArray(), indicies.ToArray(), radius, vertexInfoCollection); }