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
            });
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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));
        }
Exemple #5
0
        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);
        }
Exemple #7
0
 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
                                                    ));
 }
Exemple #8
0
 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
            ));
 }
Exemple #9
0
        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));
        }
Exemple #10
0
        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);
        }
Exemple #12
0
        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
                       ));
        }
Exemple #13
0
        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));
        }
Exemple #14
0
        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
            });
        }
Exemple #17
0
 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);
 }
Exemple #18
0
 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));
 }