/// <summary> /// Create a TerrainComputer for a specific mapData/terrain instance. /// </summary> /// <param name="mapPixelData"></param> /// <param name="sampler"></param> /// <returns></returns> public static TerrainComputer Create(MapPixelData mapPixelData, InterestingTerrainSampler sampler) { var tSize = Utility.GetTerrainVertexSize(); return(new TerrainComputer() { sampler = sampler, heightmapBuffers = BufferIO.CreateHeightmapBuffers(), heightmapResolution = (int)InterestingTerrains.settings.heightmapResolution, locationRect = mapPixelData.hasLocation ? mapPixelData.locationRect : new Rect(-10, -10, 1, 1), terrainPosition = Utility.GetTerrainVertexPosition(mapPixelData.mapPixelX, mapPixelData.mapPixelY), terrainSize = new Vector2(tSize, tSize) }); }
/// <summary> /// Initializes and runs a TerrainComputer GPU job, then processes the generated data. /// </summary> /// <param name="csPrototype"></param> /// <param name="mapData"></param> /// <param name="csParams"></param> public void DispatchAndProcess(ComputeShader csPrototype, ref MapPixelData mapData, TerrainComputerParams csParams) { var woodsFile = DaggerfallUnity.Instance.ContentReader.WoodsFileReader; var cs = UnityEngine.Object.Instantiate(csPrototype); var k = cs.FindKernel("TerrainComputer"); uint _x, _y, _z; cs.GetKernelThreadGroupSizes(k, out _x, out _y, out _z); int res = heightmapResolution + 1; DaggerfallUnity dfUnity; DaggerfallUnity.FindDaggerfallUnity(out dfUnity); int searchSize = 16; var locations = new List <Rect>(); int x, y; for (x = -searchSize; x <= searchSize; x++) { for (y = -searchSize; y <= searchSize; y++) { var mpx = mapData.mapPixelX + x; var mpy = mapData.mapPixelY + y; var key = new DoubleInt() { Item1 = mpx, Item2 = mpy }; if (locationRectCache.ContainsKey(key)) { locations.Add(locationRectCache[key]); continue; } var mapPixelPos = new DFPosition(mpx, mpy); var mapPixelData = TerrainHelper.GetMapPixelData(dfUnity.ContentReader, mpx, mpy); if (!mapPixelData.hasLocation) { continue; } var location = dfUnity.ContentReader.MapFileReader.GetLocation(mapPixelData.mapRegionIndex, mapPixelData.mapLocationIndex); var locationRect = GetLocationRect(location); if (locationRect.width == 0 || locationRect.height == 0) { continue; } locationRect = ExpandInEachDirection(locationRect, 1); locationRectCache.Add(key, locationRect); locations.Add(locationRect); } } x = (int)_x; y = (int)_y; cs.SetVector("terrainPosition", terrainPosition); cs.SetVector("terrainSize", terrainSize); cs.SetInt("heightmapResolution", heightmapResolution); cs.SetVector("locationPosition", locationRect.min); cs.SetVector("locationSize", locationRect.size); cs.SetVectorArray("locationPositions", locations.Select(r => new Vector4(r.min.x, r.min.y)).ToArray()); cs.SetVectorArray("locationSizes", locations.Select(r => new Vector4(r.size.x, r.size.y)).ToArray()); cs.SetInt("locationCount", locations.Count); cs.SetTexture(k, "BiomeMap", InterestingTerrains.biomeMap); cs.SetTexture(k, "DerivMap", InterestingTerrains.derivMap); cs.SetTexture(k, "tileableNoise", InterestingTerrains.tileableNoise); cs.SetFloat("originalHeight", Utility.GetOriginalTerrainHeight()); cs.SetFloat("newHeight", Constants.TERRAIN_HEIGHT); cs.SetTexture(k, "mapPixelHeights", baseHeightmap); cs.SetBuffer(k, "heightmapBuffer", heightmapBuffers.heightmapBuffer); cs.SetBuffer(k, "rawNoise", heightmapBuffers.rawNoise); cs.SetBuffer(k, "locationHeightData", locationHeightData); cs.SetVector("worldSize", Utility.GetWorldVertexSize()); var rd = Compatibility.BasicRoadsUtils.GetRoadData(mapData.mapPixelX, mapData.mapPixelY); cs.SetVectorArray("NW_NE_SW_SE", rd.NW_NE_SW_SE); cs.SetVectorArray("N_E_S_W", rd.N_E_S_W); csParams.ApplyToCS(cs); woodsFile.Buffer = originalHeightmapBuffer; HandleBaseMapSampleParams(ref mapData, ref cs, k); woodsFile.Buffer = alteredHeightmapBuffer; cs.Dispatch(k, res / x, res / y, 1); k = cs.FindKernel("TilemapComputer"); cs.SetTexture(k, "BiomeMap", InterestingTerrains.biomeMap); cs.SetTexture(k, "DerivMap", InterestingTerrains.derivMap); cs.SetBuffer(k, "heightmapBuffer", heightmapBuffers.heightmapBuffer); cs.SetBuffer(k, "tilemapData", heightmapBuffers.tilemapData); cs.SetBuffer(k, "rawNoise", heightmapBuffers.rawNoise); cs.Dispatch(k, res / x, res / y, 1); BufferIO.ProcessBufferValuesAndDispose(heightmapBuffers, ref mapData); }