public async Task <TextureWithSize> GenerateHeightDetailElementAsync(MyRectangle requestedArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus) { var textureWithSize = await RetriveFoundationTextureAsync(requestedArea, resolution, cornersMergeStatus); var workTexture = new TextureWithCoords(sizedTexture: textureWithSize, coords: requestedArea); foreach (var applier in _featureAppliers.Where(c => c.AvalibleResolutions.Contains(resolution)) .OrderBy(c => c.Rank)) { workTexture = await applier.Applier.ApplyFeatureAsync(workTexture, resolution, false); //todo var localTexture = workTexture; await _commonExecutor.AddAction(() => localTexture.Texture.wrapMode = TextureWrapMode.Clamp); } var textureWithMipMaps = await GenerateTextureWithMipMapsAsync(new TextureWithSize() { Size = textureWithSize.Size, Texture = workTexture.Texture }); return(new TextureWithSize() { Size = textureWithSize.Size, Texture = textureWithMipMaps }); }
public override async Task <TerrainDetailElementOutput> RetriveTerrainDetailAsync( TerrainDescriptionElementTypeEnum type, MyRectangle queryArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus) { TerrainDetailElement detailElement = null; CornersMergeStatus status = CornersMergeStatus.MERGED; if (cornersMergeStatus == RequiredCornersMergeStatus.NOT_MERGED) { status = CornersMergeStatus.NOT_MERGED; } if (type == TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY) { detailElement = await _provider.GenerateHeightDetailElementAsync(queryArea, resolution, status); } else if (type == TerrainDescriptionElementTypeEnum.NORMAL_ARRAY) { detailElement = await _provider.GenerateNormalDetailElementAsync(queryArea, resolution, status); } else { Preconditions.Fail("Not supported type: " + type); } return(new TerrainDetailElementOutput() { TokenizedElement = new TokenizedTerrainDetailElement() { DetailElement = detailElement, Token = null }, UvBase = null }); }
public async Task<TerrainDescriptionOutput> QueryAsync(TerrainDescriptionQuery query) { Dictionary<TerrainDescriptionElementTypeEnum, TerrainDetailElementOutput> elementsDict = new Dictionary<TerrainDescriptionElementTypeEnum, TerrainDetailElementOutput>(); var queryArea = query.QueryArea; foreach (var elementDetail in query.RequestedElementDetails) { elementDetail.Resolution = TerrainCardinalResolution.ToSingletonResolution(elementDetail.Resolution); AssertResolutionIsCompilant(queryArea, elementDetail.Resolution); var type = elementDetail.Type; TerrainDetailElementOutput element = null; if (type == TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY) { element = await RetriveHeightArrayAsync(queryArea, elementDetail.Resolution, elementDetail.RequiredMergeStatus); //Debug.Log("E651: " + query.QueryArea+ $" and outUV is {element.UvBase}"); } else if (type == TerrainDescriptionElementTypeEnum.NORMAL_ARRAY) { element = await RetriveNormalArrayAsync(queryArea, elementDetail.Resolution, elementDetail.RequiredMergeStatus); } else { Preconditions.Fail("Tesselation map unsupported!!!"); } elementsDict[type] = element; } return new TerrainDescriptionOutput(elementsDict); }
public static MyRectangle GetAlignedTerrainArea(IntVector2 griddedArea, TerrainCardinalResolution cardinalResolution, int terrainDetailImageSideResolution) { var alignLength = cardinalResolution.DetailResolution.MetersPerPixel * terrainDetailImageSideResolution; return(new MyRectangle(griddedArea.X * alignLength, griddedArea.Y * alignLength, alignLength, alignLength)); }
private async Task <TerrainDetailElement> GenerateTerrainDetailElementAsync( MyRectangle queryArea, TerrainCardinalResolution cardinalResolution, CornersMergeStatus requiredMerge, Func <MyRectangle, TerrainCardinalResolution, TextureWithSize, Task <TextureWithSize> > cornerMergingFunc, Func <MyRectangle, TerrainCardinalResolution, RequiredCornersMergeStatus, Task <TextureWithSize> > generateElementFunc ) { var newTerrainArea = _alignmentCalculator.ComputeAlignedTerrainArea(queryArea, cardinalResolution); RetrivedTerrainDetailTexture texture = null; CornersMergeStatus outCornersMergeStatus; TextureWithSize outTexture = null; var baseTexture = await generateElementFunc(newTerrainArea, cardinalResolution, RequiredCornersMergeStatus.NOT_MERGED); if (requiredMerge == CornersMergeStatus.NOT_MERGED) { outTexture = baseTexture; outCornersMergeStatus = CornersMergeStatus.NOT_MERGED; } else { outTexture = await cornerMergingFunc(queryArea, cardinalResolution, baseTexture); outCornersMergeStatus = CornersMergeStatus.MERGED; } return(new TerrainDetailElement() { DetailArea = newTerrainArea, Resolution = cardinalResolution, Texture = outTexture, CornersMergeStatus = outCornersMergeStatus }); }
public MyRectangle ComputeAlignedTerrainArea(MyRectangle queryArea, TerrainCardinalResolution cardinalResolution) { var newTerrainArea = TerrainShapeUtils.GetAlignedTerrainArea(queryArea, cardinalResolution, _terrainDetailImageSideDisjointResolution); return(newTerrainArea); }
public async Task <TerrainDetailElement> GenerateNormalDetailElementAsync(MyRectangle queryArea, TerrainCardinalResolution cardinalResolution, CornersMergeStatus requiredMerge) { return(await GenerateTerrainDetailElementAsync(queryArea, cardinalResolution, requiredMerge, ((rectangle, resolution, textureWithSize) => TaskUtils.MyFromResult(textureWithSize)), // we do not have to merge normals - just generate normals from merged heightmap! _generator.GenerateNormalDetailElementAsync )); }
public static IntVector2 RetriveTextureSize(MyRectangle area, TerrainCardinalResolution resolution) { return(new IntVector2 ( Mathf.RoundToInt(area.Width * resolution.DetailResolution.PixelsPerMeter) + 1, Mathf.RoundToInt(area.Width * resolution.DetailResolution.PixelsPerMeter) + 1 )); }
public static IntVector2 GetGriddedTerrainArea(MyRectangle alignedArea, TerrainCardinalResolution cardinalResolution, int terrainDetailImageSideResolution) { var alignLength = cardinalResolution.DetailResolution.MetersPerPixel * terrainDetailImageSideResolution; var startX = Mathf.RoundToInt(alignedArea.X / (float)alignLength); var startY = Mathf.RoundToInt(alignedArea.Y / (float)alignLength); return(new IntVector2(startX, startY)); }
public static MyRectangle GetAlignedTerrainArea(MyRectangle queryArea, TerrainCardinalResolution cardinalResolution, int terrainDetailImageSideResolution) { var alignLength = cardinalResolution.DetailResolution.MetersPerPixel * terrainDetailImageSideResolution; var startX = Mathf.FloorToInt(queryArea.X / (float)alignLength) * alignLength; var startY = Mathf.FloorToInt(queryArea.Y / (float)alignLength) * alignLength; return(new MyRectangle(startX, startY, alignLength, alignLength)); }
public void AssertResolutionIsCompilant(MyRectangle queryArea, TerrainCardinalResolution elementDetailResolution) { //in other words, it is not too big var maxLength = elementDetailResolution.DetailResolution.MetersPerPixel * _terrainDetailImageSideDisjointResolution; Preconditions.Assert(queryArea.Width <= maxLength, "Too wide query area. Width is " + queryArea.Width); Preconditions.Assert(queryArea.Height <= maxLength, "Too tall query area. Height is " + queryArea.Height); }
private MyRectangle RetriveAlignedArea(Vector2 startPosition, TerrainCardinalResolution resolution) { var cellSize = TerrainDescriptionConstants.DetailCellSizesPerResolution[resolution]; return(new MyRectangle( Mathf.FloorToInt(startPosition.x / cellSize) * cellSize, Mathf.FloorToInt(startPosition.y / cellSize) * cellSize, cellSize, cellSize )); }
private MyRectangle GetAlignedUv(MyRectangle queryArea, TerrainCardinalResolution resolution) { float alignLength = TerrainDescriptionConstants.DetailCellSizesPerResolution[resolution]; var alignedBox = new MyRectangle( Mathf.FloorToInt(queryArea.X / alignLength) * alignLength, Mathf.FloorToInt(queryArea.Y / alignLength) * alignLength, alignLength, alignLength ); return(RectangleUtils.CalculateSubelementUv(alignedBox, queryArea)); }
public async Task <TerrainDetailElement> GenerateHeightDetailElementAsync(MyRectangle queryArea, TerrainCardinalResolution cardinalResolution, CornersMergeStatus requiredMerge) { Func <MyRectangle, TerrainCardinalResolution, TextureWithSize, Task <TextureWithSize> > cornerMergingFunc = null; if (_cornerMerger != null) { cornerMergingFunc = _cornerMerger.MergeHeightDetailCorners; } return(await GenerateTerrainDetailElementAsync(queryArea, cardinalResolution, requiredMerge, cornerMergingFunc, _generator.GenerateHeightDetailElementAsync )); }
public override async Task <TerrainDetailElementOutput> RetriveTerrainDetailAsync( TerrainDescriptionElementTypeEnum type, MyRectangle queryArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus) { var queryOutput = await _db.QueryAsync(new TerrainDescriptionQuery() { QueryArea = queryArea, RequestedElementDetails = new List <TerrainDescriptionQueryElementDetail>() { new TerrainDescriptionQueryElementDetail() { Resolution = resolution, Type = type, RequiredMergeStatus = cornersMergeStatus } } }); return(queryOutput.GetElementOfType(type)); }
private async Task <TextureWithSize> RetriveFoundationTextureAsync(MyRectangle requestedArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus) { Texture fundationTexture = null; MyRectangle renderCoords = null; TerrainDetailElementToken retrivedElementToken = null; if (resolution == TerrainCardinalResolution.MIN_RESOLUTION) { fundationTexture = _fullFundationTextureData.Texture; renderCoords = TerrainShapeUtils.ComputeUvOfSubElement(requestedArea, _fullFundationTextureData.Coords); } else { var lowerResolution = resolution.LowerResolution; var fundationQueryArea = TerrainShapeUtils.GetAlignedTerrainArea(requestedArea, lowerResolution, _configuration.TerrainDetailImageSideDisjointResolution); var foundationOutput = await _baseTerrainDetailProvider.RetriveTerrainDetailAsync( TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY, fundationQueryArea, lowerResolution, cornersMergeStatus); retrivedElementToken = foundationOutput.TokenizedElement.Token; var fundationDetailElement = foundationOutput.TokenizedElement.DetailElement; renderCoords = TerrainShapeUtils.ComputeUvOfSubElement(requestedArea, fundationDetailElement.DetailArea); fundationTexture = fundationDetailElement.Texture.Texture; await _commonExecutor.AddAction(() => fundationTexture.filterMode = FilterMode.Bilinear); } IntVector2 outTextureSize = TerrainShapeUtils.RetriveTextureSize(requestedArea, resolution); UniformsPack pack = new UniformsPack(); pack.SetTexture("_SourceTexture", fundationTexture); ConventionalTextureInfo outTextureInfo = new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true); TextureRenderingTemplate template = new TextureRenderingTemplate() { CanMultistep = false, Coords = renderCoords, OutTextureInfo = outTextureInfo, RenderTextureFormat = RenderTextureFormat.RFloat, ShaderName = "Custom/TerGen/Cutting", UniformPack = pack, CreateTexture2D = false }; var outTex = await _rendererProxy.AddOrder(template); await _commonExecutor.AddAction(() => outTex.wrapMode = TextureWrapMode.Clamp); if (retrivedElementToken != null) { await _baseTerrainDetailProvider.RemoveTerrainDetailAsync(retrivedElementToken); } return(new TextureWithSize() { Size = outTextureSize, Texture = outTex }); }
private async Task<TerrainDetailElementOutput> RetriveNormalArrayAsync(MyRectangle queryArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus requiredMerge) //todo { var alignedArea = _alignmentCalculator.ComputeAlignedTerrainArea(queryArea, resolution); return GenerateOutput( await _cachedTerrainDetailProvider.GenerateNormalDetailElementAsync(alignedArea, resolution, requiredMerge), queryArea); }
private void AssertResolutionIsCompilant(MyRectangle queryArea, TerrainCardinalResolution elementDetailResolution) { _alignmentCalculator.AssertResolutionIsCompilant(queryArea, elementDetailResolution); }
public static TerrainCardinalResolution ToSingletonResolution(TerrainCardinalResolution oldResolution) { return(AllResolutions.First(c => Equals(c._detailResolution, oldResolution._detailResolution))); }
public abstract Task <TerrainDetailElementOutput> RetriveTerrainDetailAsync( TerrainDescriptionElementTypeEnum type, MyRectangle queryArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus);
public async Task <TextureWithSize> GenerateNormalDetailElementAsync(MyRectangle requestedArea, TerrainCardinalResolution resolution, RequiredCornersMergeStatus cornersMergeStatus) { var baseHeightTextureOutput = await _baseTerrainDetailProvider.RetriveTerrainDetailAsync( TerrainDescriptionElementTypeEnum.HEIGHT_ARRAY, requestedArea, resolution, cornersMergeStatus); var baseHeightTexture = baseHeightTextureOutput.TokenizedElement.DetailElement; IntVector2 outTextureSize = TerrainShapeUtils.RetriveTextureSize(requestedArea, resolution); UniformsPack pack = new UniformsPack(); float heightMultiplier = 0; if (resolution == TerrainCardinalResolution.MIN_RESOLUTION) { heightMultiplier = 1.25f; } else if (resolution == TerrainCardinalResolution.MID_RESOLUTION) { heightMultiplier = 10f; } else { heightMultiplier = 80f; } pack.SetTexture("_HeightmapTex", baseHeightTexture.Texture.Texture); //pack.SetUniform("_HeightMultiplier", heightMultiplier); pack.SetUniform("_HeightMultiplier", 1); pack.SetUniform("_GlobalCoords", requestedArea.ToVector4()); ConventionalTextureInfo outTextureInfo = new ConventionalTextureInfo(outTextureSize.X, outTextureSize.Y, TextureFormat.ARGB32, true); var renderCoords = TerrainShapeUtils.ComputeUvOfSubElement(requestedArea, baseHeightTexture.DetailArea); TextureRenderingTemplate template = new TextureRenderingTemplate() { CanMultistep = false, Coords = renderCoords, OutTextureInfo = outTextureInfo, RenderTextureFormat = RenderTextureFormat.ARGB32, ShaderName = "Custom/Terrain/NormalmapGenerator", UniformPack = pack, CreateTexture2D = false }; var outTex = await _rendererProxy.AddOrder(template); await _commonExecutor.AddAction(() => outTex.filterMode = FilterMode.Trilinear); await _baseTerrainDetailProvider.RemoveTerrainDetailAsync(baseHeightTextureOutput.TokenizedElement.Token); //SavingFileManager.SaveTextureToPngFile(@"C:\temp\norm1.png", outTex as Texture2D); return(new TextureWithSize() { Size = new IntVector2(outTextureSize.X, outTextureSize.Y), Texture = outTex }); }
public MyRectangle GetAlignedTerrainArea(IntVector2 griddedArea, TerrainCardinalResolution cardinalResolution) { return(TerrainShapeUtils.GetAlignedTerrainArea(griddedArea, cardinalResolution, _terrainDetailImageSideDisjointResolution)); }
public MyRectangle GetAlignedTerrainArea(MyRectangle queryArea, TerrainCardinalResolution cardinalResolution) { return(TerrainShapeUtils.GetAlignedTerrainArea(queryArea, cardinalResolution, _terrainDetailImageSideDisjointResolution)); }