public ChunkOrientationData MakeOrientationRequestForChunk(IMapChunk chunk) { var newData = new ChunkOrientationData(chunk); UnrenderedOrientationData.Add(newData); return(newData); }
public void ReleaseOrientationData(ChunkOrientationData data) { FreeBakerTriplets.Enqueue(data.BakerTriplet); data.BakerTriplet = null; }
private IEnumerator RefreshAlphamap(ChunkOrientationData orientationData) { var terrainData = Terrain.terrainData; var unsafeOrientationTexture = new AsyncTextureUnsafe <Color32>(orientationData.OrientationTexture); var unsafeWeightsTexture = new AsyncTextureUnsafe <Color32>(orientationData.WeightsTexture); var unsafeDuckTexture = new AsyncTextureUnsafe <Color32>(orientationData.DuckTexture); Vector3 terrainSize = terrainData.size; int mapWidth = terrainData.alphamapWidth; int mapHeight = terrainData.alphamapHeight; int alphamapLength = RenderConfig.MapTextures.Count(); float[,,] alphaMaps = terrainData.GetAlphamaps(0, 0, mapWidth, mapHeight); float maxTextureNormalX = Width / RenderConfig.ChunkWidth; float maxTextureNormalZ = Height / RenderConfig.ChunkHeight; float indexToNormalX = 1f / (mapHeight - 1f); float indexToNormalZ = 1f / (mapWidth - 1f); Vector3 chunkPosition = transform.position; var columnTasks = new Task[mapHeight]; for (int height = 0; height < mapHeight; height++) { int cachedHeight = height; var indexBytes = new byte[2]; PointOrientationData pointOrientation = new PointOrientationData(); float[] returnMap = new float[RenderConfig.MapTextures.Count()]; float[] intermediateMap = new float[RenderConfig.MapTextures.Count()]; var columnTask = new Task(() => { for (int width = 0; width < mapWidth; width++) { float terrainNormalX, terrainNormalZ, textureNormalX, textureNormalZ, worldX, worldZ; Color32 orientationColor; Color weightsColor, duckColor; //For some reason, terrainData seems to index its points //as (y, x) rather than the more traditional (x, y), so //we need to sample our texture accordingly terrainNormalX = cachedHeight * indexToNormalX; terrainNormalZ = width * indexToNormalZ; worldX = chunkPosition.x + terrainNormalX * terrainSize.x; worldZ = chunkPosition.z + terrainNormalZ * terrainSize.z; textureNormalX = maxTextureNormalX * terrainNormalX; textureNormalZ = maxTextureNormalZ * terrainNormalZ; orientationColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeOrientationTexture)); weightsColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeWeightsTexture)); duckColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeDuckTexture)); PointOrientationLogic.GetOrientationDataFromColors( pointOrientation, indexBytes, orientationColor, weightsColor, duckColor ); AlphamapLogic.GetAlphamapFromOrientation(returnMap, intermediateMap, pointOrientation); for (int alphaIndex = 0; alphaIndex < alphamapLength; alphaIndex++) { alphaMaps[width, cachedHeight, alphaIndex] = returnMap[alphaIndex]; } } }); columnTask.Start(); columnTasks[cachedHeight] = columnTask; } while (columnTasks.Any(task => !task.IsCompleted)) { yield return(SkipFrame); } terrainData.SetAlphamaps(0, 0, alphaMaps); }
private IEnumerator RefreshHeightmap(ChunkOrientationData chunkOrientation) { var terrainData = Terrain.terrainData; var unsafeOrientationTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.OrientationTexture); var unsafeWeightsTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.WeightsTexture); var unsafeDuckTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.DuckTexture); var unsafeFlatlandsNoise = new AsyncTextureUnsafe <Color32>(RenderConfig.FlatlandsElevationNoiseSource); var unsafeHillsNoise = new AsyncTextureUnsafe <Color32>(RenderConfig.HillsElevationNoiseSource); Vector3 terrainSize = terrainData.size; int mapWidth = terrainData.heightmapWidth; int mapHeight = terrainData.heightmapHeight; float[,] heights = terrainData.GetHeights(0, 0, mapWidth, mapHeight); float maxTextureNormalX = Width / RenderConfig.ChunkWidth; float maxTextureNormalZ = Height / RenderConfig.ChunkHeight; float indexToNormalX = 1f / (mapHeight - 1f); float indexToNormalZ = 1f / (mapWidth - 1f); Vector3 chunkPosition = transform.position; var columnTasks = new Task[mapHeight]; for (int height = 0; height < mapHeight; height++) { int cachedHeight = height; var indexBytes = new byte[2]; PointOrientationData pointOrientation = new PointOrientationData(); var columnTask = new Task(() => { for (int width = 0; width < mapWidth; width++) { float terrainNormalX, terrainNormalZ, textureNormalX, textureNormalZ, worldX, worldZ; Color32 orientationColor; Color weightsColor, duckColor; //For some reason, terrainData seems to index its points //as (y, x) rather than the more traditional (x, y), so //we need to sample our texture accordingly terrainNormalX = cachedHeight * indexToNormalX; terrainNormalZ = width * indexToNormalZ; worldX = chunkPosition.x + terrainNormalX * terrainSize.x; worldZ = chunkPosition.z + terrainNormalZ * terrainSize.z; textureNormalX = maxTextureNormalX * terrainNormalX; textureNormalZ = maxTextureNormalZ * terrainNormalZ; orientationColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeOrientationTexture)); weightsColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeWeightsTexture)); duckColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeDuckTexture)); PointOrientationLogic.GetOrientationDataFromColors( pointOrientation, indexBytes, orientationColor, weightsColor, duckColor ); heights[width, cachedHeight] = HeightLogic.GetHeightForPoint( new Vector2(worldX, worldZ), pointOrientation, unsafeFlatlandsNoise, unsafeHillsNoise ); } }); columnTask.Start(); columnTasks[cachedHeight] = columnTask; } while (columnTasks.Any(task => !task.IsCompleted)) { yield return(SkipFrame); } terrainData.SetHeights(0, 0, heights); }
private IEnumerator Refresh_Perform() { MapRenderingSignals.ChunkStartingToRefresh.OnNext(this); yield return(SkipFrame); while (FullMapRefresher.IsRefreshingRivers) { yield return(SkipFrame); } yield return(SkipFrame); bool flushTerrain = false; if ((RefreshFlags & TerrainRefreshType.RequiresOrientation) != 0) { ChunkOrientationData orientationData = OrientationBaker.MakeOrientationRequestForChunk(this); while (!orientationData.IsReady) { yield return(SkipFrame); } if (((RefreshFlags & TerrainRefreshType.Alphamap) == TerrainRefreshType.Alphamap)) { yield return(StartCoroutine(RefreshAlphamap(orientationData))); flushTerrain = true; } if (((RefreshFlags & TerrainRefreshType.Heightmap) == TerrainRefreshType.Heightmap)) { yield return(StartCoroutine(RefreshHeightmap(orientationData))); flushTerrain = true; } OrientationBaker.ReleaseOrientationData(orientationData); } if (((RefreshFlags & TerrainRefreshType.Water) == TerrainRefreshType.Water)) { RefreshWater(); } if (flushTerrain) { Terrain.Flush(); if (Terrain.topNeighbor != null) { Terrain.topNeighbor.Flush(); } if (Terrain.rightNeighbor != null) { Terrain.rightNeighbor.Flush(); } if (Terrain.bottomNeighbor != null) { Terrain.bottomNeighbor.Flush(); } if (Terrain.leftNeighbor != null) { Terrain.leftNeighbor.Flush(); } yield return(SkipFrame); } if (((RefreshFlags & TerrainRefreshType.Culture) == TerrainRefreshType.Culture)) { RefreshCulture(); } if (((RefreshFlags & TerrainRefreshType.Features) == TerrainRefreshType.Features)) { RefreshFeatures(); } if (((RefreshFlags & TerrainRefreshType.Roads) == TerrainRefreshType.Roads)) { RefreshRoads(); } if (((RefreshFlags & TerrainRefreshType.Marshes) == TerrainRefreshType.Marshes)) { RefreshMarshes(); } if (((RefreshFlags & TerrainRefreshType.Oases) == TerrainRefreshType.Oases)) { RefreshOases(); } if (((RefreshFlags & TerrainRefreshType.Visibility) == TerrainRefreshType.Visibility)) { RefreshVisibility(); } RefreshFlags = TerrainRefreshType.None; RefreshCoroutine = null; MapRenderingSignals.ChunkFinishedRefreshing.OnNext(this); }