protected override void MeshForCoord(ref MeshDetails details, int x, int y, int z, Chunk chunk) { ChunkPiece curr = null; ChunkPiece checking; try { curr = chunk.GetPieceRollover(x, y, z); } catch (NoChunkException nce) { } // if the current block is empty, skip it if (curr == null) { return; } // check each direction for (int i = 0; i < s_DirOffsets.GetLength(0); i++) { try { checking = chunk.GetPieceRollover( x + s_DirOffsets[i, 0], y + s_DirOffsets[i, 1], z + s_DirOffsets[i, 2] ); } catch (NoChunkException nce) { if (!DrawEdgeChunkWalls) { // if there is no chunk there, don't draw the edge continue; } checking = null; } // if the checking block is empty if (checking == null) { // generate the desired face Face(ref details, x, y, z, i, chunk.ChunkScale, curr); } } }
protected virtual IEnumerator GenerateMeshRoutine(Chunk chunk) { MeshDetails details = new MeshDetails(); Mesh m = chunk.ChunkFilter.mesh; chunk.ChunkRenderer.material = m_Material; int[] vals = new int[3]; for (int i = 0; i < s_ChunkNeighbourOffset.GetLength(0); i++) { if (!chunk.Parent) { continue; } try { Chunk c = chunk.Parent [chunk.GroupCoord + s_ChunkNeighbourOffset[i]]; } catch (NoChunkException nce) { vals[i] = -1; } } for (int x = vals[0]; x < chunk.ChunkSize; x++) { for (int y = vals[1]; y < chunk.ChunkSize; y++) { for (int z = vals[2]; z < chunk.ChunkSize; z++) { MeshForCoord(ref details, x, y, z, chunk); details.LoadIntoMesh(ref m); if (m_RoutineDelay != 0) { yield return(new WaitForSeconds(m_RoutineDelay)); } } } } chunk.ChunkFilter.sharedMesh = chunk.ChunkCollider.sharedMesh = m; }
private void Face(ref MeshDetails details, int x, int y, int z, int arrIndex, float scale, ChunkPiece cp) { int i; // vertices for (i = 0; i < s_FaceCorners.GetLength(1); i++) { // the face array is used to access the given cube corner index Vector3 point = new Vector3( x + s_CubeCorners[s_FaceCorners[arrIndex, i], 0], y + s_CubeCorners[s_FaceCorners[arrIndex, i], 1], z + s_CubeCorners[s_FaceCorners[arrIndex, i], 2] ) * scale; details.AddPoint(point); details.AddTri(details.Tris.Count); details.AddUV(cp.GetUV(s_UVLookup[s_UVCorners[arrIndex, i]])); } // UVs // Normals? }
protected abstract void MeshForCoord(ref MeshDetails details, int x, int y, int z, Chunk chunk);
protected override void MeshForCoord(ref MeshDetails details, int x, int y, int z, Chunk chunk) { MarchCube(ref details, x, y, z, chunk); }
private void MarchCube(ref MeshDetails md, int x, int y, int z, Chunk chunk) { // corners of the currently marching cube ChunkPiece[] mvCorners = new ChunkPiece[8]; // store each corner in a local array for (int vertex = 0; vertex < s_CubeVertexOffset.GetLength(0) /* 8 */; vertex++) { try { mvCorners[vertex] = chunk.GetPieceRollover( x + s_CubeVertexOffset[vertex, 0], y + s_CubeVertexOffset[vertex, 1], z + s_CubeVertexOffset[vertex, 2] ); } catch (NoChunkException nce) { if (!DrawEdgeChunkWalls) { return; } mvCorners[vertex] = null; } } // find which corners are/aren't inside the surface int flagIndex = 0; for (int vertexTest = 0; vertexTest < s_CubeVertexOffset.GetLength(0) /* 8 */; vertexTest++) { // if there is something there, set the bit if (mvCorners[vertexTest] == null) { flagIndex |= 1 << vertexTest; } } // Find which edges intersect the surface int edgeFlags = s_CubeEdgeFlags[flagIndex]; // if fully in/out of the surface, don't draw it if (edgeFlags == 0) { return; } Vector3[] edgeVerticies = new Vector3[12]; Vector3[] edgeNorms = new Vector3[12]; Vector2[] edgeUVs = new Vector2[12]; Color[] edgeCols = new Color[12]; float offset; // find the edge intersection point along each relevant edge for (int edge = 0; edge < s_CubeEdgeConnection.GetLength(0) /* 8 */; edge++) { // if there was not an intersection if ((edgeFlags & (1 << edge)) == 0) { // skip it continue; } /* * // some complicated thing to get it looking less blocky ... * offset = GetOffset( * mvCorners[s_CubeEdgeConnection[edge, 0]] != null ? 1 : 0, * mvCorners[s_CubeEdgeConnection[edge, 1]] != null ? 1 : 0, * fTargetValue * ); */ offset = 0.5f; Vector3 vec = new Vector3(x, y, z); for (int i = 0; i < 3; i++) { edgeVerticies[edge][i] = vec[i] + (s_CubeVertexOffset[s_CubeEdgeConnection[edge, 0], i] + offset * s_EdgeDirection[edge, i] * chunk.ChunkScale); } int cnrIndex = GetNonNullVertexIndex(mvCorners, edge); ChunkPiece cp = mvCorners[cnrIndex]; // check again, just in case something has gone horribly wrong if (cp != null) { edgeCols[edge] = cp.PieceColour; } // edgeNorms[edge] = GetNormal(edgeVerticies[edge].x, edgeVerticies[edge].y, edgeVerticies[edge].z); } Vector3 vertexOffset = Vector3.one * chunk.ChunkScale * 0.5f; // draw the relevant triangles. Up to 5 per cube. for (int tri = 0; tri < 5; tri++) { // no more triangles if this is true if (s_TriangleConnectionTable[flagIndex, 3 * tri] < 0) { break; } int baseN = md.Points.Count; for (int cnr = 0; cnr < 3; cnr++) { int vertIndex = s_TriangleConnectionTable[flagIndex, 3 * tri + cnr]; md.AddTri(baseN + cnr); md.AddPoint(edgeVerticies[vertIndex] + vertexOffset); md.AddUV(edgeUVs[vertIndex]); md.AddColour(edgeCols[vertIndex]); } } }