public void RequestWorldChunkMeshData(WorldChunk chunk, WorldChunkSideBorders sideBorder, WorldChunkSettings setting, Action <MeshData> callback) { ThreadStart threadStart = delegate { // Loading MeshData meshData = MeshGenerator.GenerateWorldChunkMesh(chunk, sideBorder, setting); lock (chunkMeshThreadInQueue) { chunkMeshThreadInQueue.Enqueue(new MeshDataThreadInfo <MeshData>(callback, meshData)); } // End Loading.. }; new Thread(threadStart).Start(); }
public static MeshData GenerateWorldChunkMesh(WorldChunk chunk, WorldChunkSideBorders borders, WorldChunkSettings setting) { int size = setting.scaledSize; int meshSize = size + 1; // One line on top/left to create the triangles between chunks int borderedSize = meshSize + 2; // One line on every direction to calculate normals of triangle on the border of mesh float offset = (meshSize - 1) / -2f; MeshData meshData = new MeshData(meshSize); // To handle normals, the mesh have to generate vertices for 1line on each 8chunks bordered int[,] vertexIndicesMap = CreateVertexIndicesMap(borderedSize); for (int y = 0; y < borderedSize; y++) { for (int x = 0; x < borderedSize; x++) { Coord chunkCoord = new Coord(x - 1, y - 1, setting); // It's start with [-1;-1] int vertexIndex = vertexIndicesMap [x, y]; float height = chunk.GetHeightValue(chunkCoord, setting); Vector2 uv = new Vector2((x - 1) / (float)(borderedSize - 2), (y - 1) / (float)(borderedSize - 2)); Vector3 vertexPosition = new Vector3( offset + uv.x * meshSize, height, offset + uv.y * meshSize ); meshData.AddOrUpdateVertex(vertexPosition, uv, vertexIndex); if (x <= borderedSize - 2 && y <= borderedSize - 2) { int a = vertexIndicesMap[x, y]; int b = vertexIndicesMap[x + 1, y]; int c = vertexIndicesMap[x, y + 1]; int d = vertexIndicesMap[x + 1, y + 1]; // Clockwise // meshData.AddTriangle (a, d, c); // meshData.AddTriangle (d, a, b); // Counter Clockwise meshData.AddTriangle(c, d, a); meshData.AddTriangle(b, a, d); } } } return(meshData); }
public void OnChunkMerged() { WorldChunkSettings setting = MapEngine.instance.worldChunkSetting; this.state = ChunkStates.Merged; if (this.requireState < ChunkStates.Merged) // If all the chunk is merged but wasn't required for (ex: side chunk with not border) { this.requireState = ChunkStates.Merged; } MapDisplay.instance.UpdateChunkDisplay(this); this.isMeshing = true; // Create the first time the chunk borders values this.chunkBorders = new WorldChunkSideBorders(this, setting); // Request Mesh data MapThreading.instance.RequestWorldChunkMeshData(this, this.chunkBorders, setting, OnWorldChunkMeshReceived); }