public float GetHeightForPoint( Vector2 xzPoint, PointOrientationData orientationData, AsyncTextureUnsafe <Color32> flatlandsNoise, AsyncTextureUnsafe <Color32> hillsNoise ) { float retval = 0f; if (!orientationData.IsOnGrid) { return(retval); } if (orientationData.Center != null && orientationData.CenterWeight > 0f) { retval += orientationData.CenterWeight * CellHeightmapLogic.GetHeightForPointForCell( xzPoint, orientationData.Center, orientationData.ElevationDuck, flatlandsNoise, hillsNoise ); } if (orientationData.Left != null && orientationData.LeftWeight > 0f) { retval += orientationData.LeftWeight * CellHeightmapLogic.GetHeightForPointForCell( xzPoint, orientationData.Left, orientationData.ElevationDuck, flatlandsNoise, hillsNoise ); } if (orientationData.Right != null && orientationData.RightWeight > 0f) { retval += orientationData.RightWeight * CellHeightmapLogic.GetHeightForPointForCell( xzPoint, orientationData.Right, orientationData.ElevationDuck, flatlandsNoise, hillsNoise ); } if (orientationData.NextRight != null && orientationData.NextRightWeight > 0f) { retval += orientationData.NextRightWeight * CellHeightmapLogic.GetHeightForPointForCell( xzPoint, orientationData.NextRight, orientationData.ElevationDuck, flatlandsNoise, hillsNoise ); } if (orientationData.RiverWeight > 0f) { retval += orientationData.RiverWeight * RenderConfig.RiverTroughElevation; } return(retval); }
public void GetOrientationDataFromColors( PointOrientationData dataToUse, byte[] indexBytes, Color32 orientationColor, Color weightsColor, Color duckColor ) { indexBytes[0] = orientationColor.r; indexBytes[1] = orientationColor.g; int index = BitConverter.ToInt16(indexBytes, 0) - 1; var center = index >= 0 && index < Grid.Cells.Count ? Grid.Cells[index] : null; HexDirection sextant = (HexDirection)orientationColor.b; if (center != null) { dataToUse.IsOnGrid = true; dataToUse.Center = center; dataToUse.Left = Grid.GetNeighbor(center, sextant.Previous()); dataToUse.Right = Grid.GetNeighbor(center, sextant); dataToUse.NextRight = Grid.GetNeighbor(center, sextant.Next()); dataToUse.CenterWeight = weightsColor.r; dataToUse.LeftWeight = weightsColor.g; dataToUse.RightWeight = weightsColor.b; dataToUse.NextRightWeight = weightsColor.a; float weightSum = weightsColor.r + weightsColor.g + weightsColor.b + weightsColor.a; dataToUse.RiverWeight = Mathf.Clamp01(1f - weightSum); dataToUse.ElevationDuck = duckColor.r; } else { dataToUse.Clear(); } }
public void GetAlphamapFromOrientation(float[] returnMap, float[] intermediateMap, PointOrientationData orientationData) { for (int i = 0; i < returnMap.Length; i++) { returnMap[i] = 0f; } if (orientationData.IsOnGrid) { if (orientationData.RiverWeight > 0f) { AddToMap( returnMap, orientationData.Center.Terrain == CellTerrain.FloodPlains ? RenderConfig.FloodPlainsAlphamap : RenderConfig.RiverAlphamap, orientationData.RiverWeight ); } if (orientationData.CenterWeight > 0f) { CellAlphamapLogic.GetAlphamapForCell(intermediateMap, orientationData.Center); AddToMap(returnMap, intermediateMap, orientationData.CenterWeight); } if (orientationData.Left != null && orientationData.LeftWeight > 0f) { CellAlphamapLogic.GetAlphamapForCell(intermediateMap, orientationData.Left); AddToMap(returnMap, intermediateMap, orientationData.LeftWeight); } if (orientationData.Right != null && orientationData.RightWeight > 0f) { CellAlphamapLogic.GetAlphamapForCell(intermediateMap, orientationData.Right); AddToMap(returnMap, intermediateMap, orientationData.RightWeight); } if (orientationData.NextRight != null && orientationData.NextRightWeight > 0f) { CellAlphamapLogic.GetAlphamapForCell(intermediateMap, orientationData.NextRight); AddToMap(returnMap, intermediateMap, orientationData.NextRightWeight); } } }
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 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); }