public override JobHandle ScheduleGenerateSamplesJob(ref MapPixelData mapPixel) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; // Divisor ensures continuous 0-1 range of height samples float div = (HeightmapDimension - 1) / 3f; // Read neighbouring height samples for this map pixel int mx = mapPixel.mapPixelX; int my = mapPixel.mapPixelY; byte sDim = 4; NativeArray <byte> shm = new NativeArray <byte>(dfUnity.ContentReader.WoodsFileReader.GetHeightMapValuesRange1Dim(mx - 2, my - 2, sDim), Allocator.TempJob); // Convert & flatten large height samples 2d array into 1d native array. byte[,] lhm2 = dfUnity.ContentReader.WoodsFileReader.GetLargeHeightMapValuesRange(mx - 1, my, 3); NativeArray <byte> lhm = new NativeArray <byte>(lhm2.Length, Allocator.TempJob); byte lDim = (byte)lhm2.GetLength(0); int i = 0; for (int y = 0; y < lDim; y++) { for (int x = 0; x < lDim; x++) { lhm[i++] = lhm2[x, y]; } } // Add both working native arrays to disposal list. mapPixel.nativeArrayList.Add(shm); mapPixel.nativeArrayList.Add(lhm); // Extract height samples for all chunks int hDim = HeightmapDimension; GenerateSamplesJob generateSamplesJob = new GenerateSamplesJob { shm = shm, lhm = lhm, heightmapData = mapPixel.heightmapData, sd = sDim, ld = lDim, hDim = hDim, div = div, mapPixelX = mapPixel.mapPixelX, mapPixelY = mapPixel.mapPixelY, maxTerrainHeight = MaxTerrainHeight, }; JobHandle generateSamplesHandle = generateSamplesJob.Schedule(hDim * hDim, 64); // Batch = 1 breaks it since shm not copied... test again later return(generateSamplesHandle); }
public override JobHandle ScheduleGenerateSamplesJob(ref MapPixelData mapPixel) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; // Divisor ensures continuous 0-1 range of tile samples float div = (float)(HeightmapDimension - 1) / 3f; // Read neighbouring height samples for this map pixel int mx = mapPixel.mapPixelX; int my = mapPixel.mapPixelY; // Seed random with terrain key UnityEngine.Random.InitState(TerrainHelper.MakeTerrainKey(mx, my)); byte[,] shm = dfUnity.ContentReader.WoodsFileReader.GetHeightMapValuesRange(mx - 2, my - 2, 4); byte[,] lhm = dfUnity.ContentReader.WoodsFileReader.GetLargeHeightMapValuesRange(mx - 1, my, 3); float[,] baseHeightValue = new float[4, 4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { int mapPixelX = Math.Max(0, Math.Min(mx + x - 2, WoodsFile.mapWidthValue)); int mapPixelY = Math.Max(0, Math.Min(my + y - 2, WoodsFile.mapHeightValue)); baseHeightValue[x, y] = shm[x, y] * ImprovedWorldTerrain.computeHeightMultiplier(mapPixelX, mapPixelY); } } float[,] waterMap = new float[4, 4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { if (shm[x, y] <= 2) // mappixel is water { waterMap[x, y] = 0.0f; } else { waterMap[x, y] = 1.0f; } } } float[,] climateMap = new float[4, 4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { int mapPixelX = Math.Max(0, Math.Min(mx + x - 2, WoodsFile.mapWidthValue)); int mapPixelY = Math.Max(0, Math.Min(my + y - 2, WoodsFile.mapHeightValue)); climateMap[x, y] = GetNoiseMapScaleBasedOnClimate(mapPixelX, mapPixelY); } } float[,] waterDistanceMap = new float[4, 4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { int mapPixelX = Math.Max(0, Math.Min(mx + x - 2, WoodsFile.mapWidthValue)); int mapPixelY = Math.Max(0, Math.Min(my + y - 2, WoodsFile.mapHeightValue)); waterDistanceMap[x, y] = (float)Math.Sqrt(ImprovedWorldTerrain.MapDistanceSquaredFromWater[mapPixelY * WoodsFile.mapWidthValue + mapPixelX]); } } float[,] noiseHeightMultiplierMap = new float[4, 4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { // interpolation multiplier taking near coast map pixels into account // (multiply with 0 at coast line and 1 at interpolationEndDistanceFromWaterForNoiseScaleMultiplier) float multFact = (Mathf.Min(interpolationEndDistanceFromWaterForNoiseScaleMultiplier, waterDistanceMap[x, y]) / interpolationEndDistanceFromWaterForNoiseScaleMultiplier); // blend watermap with climatemap taking into account multFact noiseHeightMultiplierMap[x, y] = waterMap[x, y] * climateMap[x, y] * multFact; } } float extraNoiseScaleBasedOnClimate = GetExtraNoiseScaleBasedOnClimate(mx, my); byte sDim = 4; NativeArray <float> baseHeightValueNativeArray = new NativeArray <float>(shm.Length, Allocator.TempJob); int i = 0; for (int y = 0; y < sDim; y++) { for (int x = 0; x < sDim; x++) { baseHeightValueNativeArray[i++] = baseHeightValue[x, y]; } } i = 0; NativeArray <float> noiseHeightMultiplierNativeArray = new NativeArray <float>(noiseHeightMultiplierMap.Length, Allocator.TempJob); for (int y = 0; y < sDim; y++) { for (int x = 0; x < sDim; x++) { noiseHeightMultiplierNativeArray[i++] = noiseHeightMultiplierMap[x, y]; } } // TODO - shortcut conversion & flattening. NativeArray <byte> lhmNativeArray = new NativeArray <byte>(lhm.Length, Allocator.TempJob); byte lDim = (byte)lhm.GetLength(0); i = 0; for (int y = 0; y < lDim; y++) { for (int x = 0; x < lDim; x++) { lhmNativeArray[i++] = lhm[x, y]; } } // Add the working native arrays to list for later disposal. mapPixel.nativeArrayList.Add(baseHeightValueNativeArray); mapPixel.nativeArrayList.Add(noiseHeightMultiplierNativeArray); mapPixel.nativeArrayList.Add(lhmNativeArray); // Extract height samples for all chunks int hDim = HeightmapDimension; GenerateSamplesJob generateSamplesJob = new GenerateSamplesJob { baseHeightValue = baseHeightValueNativeArray, lhm = lhmNativeArray, noiseHeightMultiplierMap = noiseHeightMultiplierNativeArray, heightmapData = mapPixel.heightmapData, sd = sDim, ld = lDim, hDim = hDim, div = div, mapPixelX = mapPixel.mapPixelX, mapPixelY = mapPixel.mapPixelY, maxTerrainHeight = MaxTerrainHeight, extraNoiseScaleBasedOnClimate = extraNoiseScaleBasedOnClimate, }; JobHandle generateSamplesHandle = generateSamplesJob.Schedule(hDim * hDim, 64); // Batch = 1 breaks it since shm not copied... test again later return(generateSamplesHandle); }