/// <summary> /// Complete terrain data update using jobs system. (second of a two stage process) /// </summary> /// <param name="terrainTexturing">Instance of ITerrainTexturing implementation class to use.</param> public void CompleteMapPixelDataUpdate(ITerrainTexturing terrainTexturing = null) { // Convert heightmap data back to standard managed 2d array. MapData.heightmapSamples = new float[heightmapDim, heightmapDim]; for (int i = 0; i < MapData.heightmapData.Length; i++) { MapData.heightmapSamples[JobA.Row(i, heightmapDim), JobA.Col(i, heightmapDim)] = MapData.heightmapData[i]; } // Convert tilemap data back to standard managed 2d array. // (Still needed for nature layout so it can be called again without requiring terrain data generation) MapData.tilemapSamples = new byte[tilemapDim, tilemapDim]; for (int i = 0; i < MapData.tilemapData.Length; i++) { byte tile = MapData.tilemapData[i]; if (tile == byte.MaxValue) { tile = 0; } MapData.tilemapSamples[JobA.Row(i, tilemapDim), JobA.Col(i, tilemapDim)] = tile; } // Create tileMap array or resize if needed and copy native array. if (TileMap == null || TileMap.Length != MapData.tileMap.Length) { TileMap = new Color32[MapData.tileMap.Length]; } MapData.tileMap.CopyTo(TileMap); // Copy max and avg heights. (TODO: Are these needed? Seem to not be used anywhere) MapData.averageHeight = MapData.avgMaxHeight[TerrainHelper.avgHeightIdx]; MapData.maxHeight = MapData.avgMaxHeight[TerrainHelper.maxHeightIdx]; DisposeNativeMemory(); }
public void Execute(int index) { int x = JobA.Row(index, tDim); int y = JobA.Col(index, tDim); // Assign tile data to tilemap Color32 tileColor = new Color32(0, 0, 0, 0); // Get sample tile data byte tile = tilemapData[JobA.Idx(x, y, tDim)]; // Convert from [flip,rotate,6bit-record] => [6bit-record,flip,rotate] int record; if (tile == byte.MaxValue) { // Zeros are converted to FF so assign tiles doesn't overwrite location tiles, convert back. record = 0; } else { record = tile * 4; if ((tile & rotBit) != 0) { record += 1; } if ((tile & flipBit) != 0) { record += 2; } } // Assign to tileMap tileColor.r = tileColor.a = (byte)record; tileMap[y * tDim + x] = tileColor; }
public void Execute(int index) { int x = JobA.Row(index, tdDim); int y = JobA.Col(index, tdDim); // Height sample for ocean and beach tiles int hx = (int)Mathf.Clamp(hDim * ((float)x / (float)tdDim), 0, hDim - 1); int hy = (int)Mathf.Clamp(hDim * ((float)y / (float)tdDim), 0, hDim - 1); float height = heightmapData[JobA.Idx(hy, hx, hDim)] * maxTerrainHeight; // x & y swapped in heightmap for TerrainData.SetHeights() // Ocean texture if (height <= oceanElevation) { tileData[index] = water; return; } // Beach texture // Adds a little +/- randomness to threshold so beach line isn't too regular if (height <= beachElevation + (JobRand.Next(-15000000, 15000000) / 10000000f)) { tileData[index] = dirt; return; } // Get latitude and longitude of this tile int latitude = (int)(mapPixelX * MapsFile.WorldMapTileDim + x); int longitude = (int)(MapsFile.MaxWorldTileCoordZ - mapPixelY * MapsFile.WorldMapTileDim + y); // Set texture tile using weighted noise float weight = 0; weight += NoiseWeight(latitude, longitude); // TODO: Add other weights to influence texture tile generation tileData[index] = GetWeightedRecord(weight); }
public void Execute(int index) { int x = JobA.Row(index, tDim); int y = JobA.Col(index, tDim); // Do nothing if in location rect as texture already set, to 0xFF if zero if (tilemapData[index] != 0) { return; } // Assign tile texture if (march) { // Get sample points int tdIdx = JobA.Idx(x, y, tdDim); int b0 = tileData[tdIdx]; // tileData[x, y] int b1 = tileData[tdIdx + 1]; // tileData[x + 1, y] int b2 = tileData[tdIdx + tdDim]; // tileData[x, y + 1] int b3 = tileData[tdIdx + tdDim + 1]; // tileData[x + 1, y + 1] int shape = (b0 & 1) | (b1 & 1) << 1 | (b2 & 1) << 2 | (b3 & 1) << 3; int ring = (b0 + b1 + b2 + b3) >> 2; int tileID = shape | ring << 4; tilemapData[index] = lookupTable[tileID]; } else { tilemapData[index] = tileData[JobA.Idx(x, y, tdDim)]; } }
public void Execute(int index) { // Use cols=x and rows=y for height data int x = JobA.Col(index, hDim); int y = JobA.Row(index, hDim); float rx = (float)x / div; float ry = (float)y / div; int ix = Mathf.FloorToInt(rx); int iy = Mathf.FloorToInt(ry); float sfracx = (float)x / (float)(hDim - 1); float sfracy = (float)y / (float)(hDim - 1); float fracx = (float)(x - ix * div) / div; float fracy = (float)(y - iy * div) / div; float scaledHeight = 0; // Bicubic sample small height map for base terrain elevation x1 = TerrainHelper.CubicInterpolator(shm[JobA.Idx(0, 3, sd)], shm[JobA.Idx(1, 3, sd)], shm[JobA.Idx(2, 3, sd)], shm[JobA.Idx(3, 3, sd)], sfracx); x2 = TerrainHelper.CubicInterpolator(shm[JobA.Idx(0, 2, sd)], shm[JobA.Idx(1, 2, sd)], shm[JobA.Idx(2, 2, sd)], shm[JobA.Idx(3, 2, sd)], sfracx); x3 = TerrainHelper.CubicInterpolator(shm[JobA.Idx(0, 1, sd)], shm[JobA.Idx(1, 1, sd)], shm[JobA.Idx(2, 1, sd)], shm[JobA.Idx(3, 1, sd)], sfracx); x4 = TerrainHelper.CubicInterpolator(shm[JobA.Idx(0, 0, sd)], shm[JobA.Idx(1, 0, sd)], shm[JobA.Idx(2, 0, sd)], shm[JobA.Idx(3, 0, sd)], sfracx); baseHeight = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, sfracy); scaledHeight += baseHeight * baseHeightScale; // Bicubic sample large height map for noise mask over terrain features x1 = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 0, ld)], lhm[JobA.Idx(ix + 1, iy + 0, ld)], lhm[JobA.Idx(ix + 2, iy + 0, ld)], lhm[JobA.Idx(ix + 3, iy + 0, ld)], fracx); x2 = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 1, ld)], lhm[JobA.Idx(ix + 1, iy + 1, ld)], lhm[JobA.Idx(ix + 2, iy + 1, ld)], lhm[JobA.Idx(ix + 3, iy + 1, ld)], fracx); x3 = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 2, ld)], lhm[JobA.Idx(ix + 1, iy + 2, ld)], lhm[JobA.Idx(ix + 2, iy + 2, ld)], lhm[JobA.Idx(ix + 3, iy + 2, ld)], fracx); x4 = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 3, ld)], lhm[JobA.Idx(ix + 1, iy + 3, ld)], lhm[JobA.Idx(ix + 2, iy + 3, ld)], lhm[JobA.Idx(ix + 3, iy + 3, ld)], fracx); noiseHeight = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, fracy); scaledHeight += noiseHeight * noiseMapScale; // Additional noise mask for small terrain features at ground level int noisex = mapPixelX * (hDim - 1) + x; int noisey = (MapsFile.MaxMapPixelY - mapPixelY) * (hDim - 1) + y; float lowFreq = TerrainHelper.GetNoise(noisex, noisey, 0.3f, 0.5f, 0.5f, 1); float highFreq = TerrainHelper.GetNoise(noisex, noisey, 0.9f, 0.5f, 0.5f, 1); scaledHeight += (lowFreq * highFreq) * extraNoiseScale; // Clamp lower values to ocean elevation if (scaledHeight < scaledOceanElevation) { scaledHeight = scaledOceanElevation; } // Set sample float height = Mathf.Clamp01(scaledHeight / maxTerrainHeight); heightmapData[index] = height; }