static void UpdateVertexesOnRange(WorldChunk chunk, int min_x, int max_x, int min_y, int max_y, int[,] vertexIndicesMap, int meshSize, int borderedSize, float offset, WorldChunkSettings setting) { for (int y = min_y; y < max_y; y++) { for (int x = min_x; x < max_x; x++) { Coord chunkCoord = new Coord(x - 1, y - 1, setting); // It's start with [-1;-1] int vertexIndex = vertexIndicesMap [x, y]; // @TODO We already know the concerned sideChunk (it's `keyValue.Value` on `UpdateChunkMesh` loop // (can be pass throw GetHeightValue to avoid search it on the list) 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 ); chunk.meshData.AddOrUpdateVertex(vertexPosition, uv, vertexIndex); } } }
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); }
// Get Height map as saved: // Size: 50x50 - Scale: 10 -> coord from [0;0] to [5;5] // coord can be on a side chunk (ex x:-1 or y:setting.scaledSize), return sidechunk value he's merged public float GetHeightValue(Coord coord, WorldChunkSettings setting) { if (this.state < ChunkStates.Merged) { return(0f); } // It's on a side chunk, get the chunk and the right coord if (coord.x < 0 || coord.y < 0 || coord.x >= setting.scaledSize || coord.y >= setting.scaledSize) { Coord chunkCoord = new Coord(this.coord.x, this.coord.y); if (coord.x < 0) { chunkCoord.x += Coord.Left.x; // x-- } else if (coord.x >= setting.scaledSize) { chunkCoord.x += Coord.Right.x; // x++ } if (coord.y < 0) { chunkCoord.y += Coord.Bottom.y; // y-- } else if (coord.y >= setting.scaledSize) { chunkCoord.y += Coord.Top.y; // y++ } // The chunk is loaded AND merged if (this.chunkBorders.sidesChunks.ContainsKey(chunkCoord)) { WorldChunk sideChunk = this.chunkBorders.sidesChunks [chunkCoord]; if (sideChunk.state >= ChunkStates.Merged) { if (coord.x < 0) { coord.x += setting.scaledSize; } else if (coord.x >= setting.scaledSize) { coord.x -= setting.scaledSize; } if (coord.y < 0) { coord.y += setting.scaledSize; } else if (coord.y >= setting.scaledSize) { coord.y -= setting.scaledSize; } return(sideChunk.GetHeightValue(coord, setting)); } } // The chunk isn't loaded.. take the nearest on the same chunk by updating the coord requested if (coord.x < 0) { coord.x = 0; } else if (coord.x >= setting.scaledSize) { coord.x = setting.scaledSize - 1; } if (coord.y < 0) { coord.y = 0; } else if (coord.y >= setting.scaledSize) { coord.y = setting.scaledSize - 1; } } // Reset index, cause x/y may was updated coord.SetIndex(setting); float noiseHeight = this.chunkData.GetHeightValue(coord); WorldZone zone = this.chunkComputed.GetZone(coord).worldZoneRef; return(MeshGenerator.GetRealHeight(noiseHeight, zone.type, setting)); }