public async Task <List <Grass2TypeWithIntensity> > GenerateMapsAsync(MyRectangle queryArea)
        {
            var habitatTextureSize = new IntVector2(
                Mathf.CeilToInt(queryArea.Width / _configuration.HabitatSamplingUnit),
                Mathf.CeilToInt(queryArea.Height / _configuration.HabitatSamplingUnit)
                );
            var habitatTexturesDict =
                await _habitatTexturesGenerator.GenerateHabitatTextures(queryArea, habitatTextureSize);

            if (!habitatTexturesDict.Any())
            {
                return(new List <Grass2TypeWithIntensity>());
            }

            UvdSizedTexture pathProximityTexture = await _pathProximityTextureDb.Query(queryArea);

            var toReturn = await _habitatToGrassIntensityMapGenerator.GenerateGrassIntenstiyAsync(queryArea,
                                                                                                  habitatTexturesDict, habitatTextureSize, pathProximityTexture);

            return(toReturn);
        }
예제 #2
0
        public async Task <List <Grass2TypeWithIntensity> > GenerateGrassIntenstiyAsync(
            MyRectangle generationArea,
            Dictionary <HabitatType, Texture2D> habitatTexturesDict,
            IntVector2 habitatTexturesSize,
            UvdSizedTexture pathProximityTexture)
        {
            var generatedGrassTypes = _configuration.GrassTypeToSourceHabitats
                                      .Where(c => c.Value.Any(k => habitatTexturesDict.ContainsKey(k))).Select(c => c.Key).ToList();

            if (!generatedGrassTypes.Any())
            {
                Debug.Log("W34 Returning empty grass intensity, Because of OutGrassTypes from habitats: " +
                          StringUtils.ToString(habitatTexturesDict.Keys));
                return(new List <Grass2TypeWithIntensity>());
            }
////////
            var usedGrassTypesPositions = CreateUsedGrassTypesPositions(generatedGrassTypes);

            var usedHabitatTypesPositions = CreateUsedHabitatTypesPositions(habitatTexturesDict);

            if (!usedHabitatTypesPositions.Any())
            {
                Debug.Log("W34 Returning empty grass intensity, Because of In habitatTypes, from habitats: " +
                          StringUtils.ToString(habitatTexturesDict.Keys));
                return(new List <Grass2TypeWithIntensity>());
            }
//////
            var habitatTextureArray = await CreateHabitatTexture2DArrayAsync(habitatTexturesDict, habitatTexturesSize);

//////

            var outFigureSize = new IntVector2(
                Mathf.CeilToInt(generationArea.Width * _configuration.OutputPixelsPerUnit),
                Mathf.CeilToInt(generationArea.Height * _configuration.OutputPixelsPerUnit)
                );

            ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer();

            MultistepComputeShader habitatToGrassShader =
                new MultistepComputeShader(_computeShaderContainer.HabitatToGrassTypeShader, outFigureSize);

            var usedKernelNames = generatedGrassTypes.Select(c => HabitatToGrassUtils.GrassTypeToKernelName[c])
                                  .ToList();

            var usedKernels = usedKernelNames.Select(c => habitatToGrassShader.AddKernel(c)).ToList();

            var usedGrassTypesPositionsBuffer =
                parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count      = usedGrassTypesPositions.Length,
                BufferData = usedGrassTypesPositions,
                Stride     = 4,
                Type       = ComputeBufferType.Default
            });

            habitatToGrassShader.SetBuffer("OutputGrassTypePositions", usedGrassTypesPositionsBuffer, usedKernels);

            var usedHabitatTypesPositionsBuffer =
                parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count      = usedHabitatTypesPositions.Length,
                BufferData = usedHabitatTypesPositions,
                Stride     = 4,
                Type       = ComputeBufferType.Default
            });

            habitatToGrassShader.SetBuffer("InputHabitatTypePositions", usedHabitatTypesPositionsBuffer, usedKernels);

            var outIntensitiesBuffer = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = outFigureSize.X * outFigureSize.Y * generatedGrassTypes.Count,
                Type   = ComputeBufferType.Default,
                Stride = 4
            });

            habitatToGrassShader.SetBuffer("OutIntensityBuffer", outIntensitiesBuffer, usedKernels);

            var habitatTextureArrayInShader = parametersContainer.AddExistingComputeShaderTexture(habitatTextureArray);

            habitatToGrassShader.SetTexture("HabitatTexturesArray", habitatTextureArrayInShader, usedKernels);

            var pathProximityTextureInShader =
                parametersContainer.AddExistingComputeShaderTexture(pathProximityTexture.TextureWithSize.Texture);

            habitatToGrassShader.SetTexture("PathProximityTexture", pathProximityTextureInShader, usedKernels);

            habitatToGrassShader.SetGlobalUniform("g_Coords", generationArea.ToVector4());
            habitatToGrassShader.SetGlobalUniform("g_PathProximityUv", pathProximityTexture.Uv.ToVector4());
            habitatToGrassShader.SetGlobalUniform("g_OutTextureSize", outFigureSize.ToFloatVec());
            habitatToGrassShader.SetGlobalUniform("g_MaxProximity", _configuration.MaxProximity);

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(
                requestedBufferIds: new List <MyComputeBufferId>()
            {
                outIntensitiesBuffer
            });

            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                OutParameters       = outParameters,
                ParametersContainer = parametersContainer,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = usedKernels
                            }
                        },
                        Shader = habitatToGrassShader
                    }
                }
            });


            var outIntensitiesNativeArray = await _commonExecutor.AddAction(() =>
            {
                var array = new float[outFigureSize.X *outFigureSize.Y *generatedGrassTypes.Count];
                outParameters.RetriveBuffer(outIntensitiesBuffer).GetData(array);
                //DebugCreateTexture(array, generationArea, outFigureSize, generatedGrassTypes.Count);

                return(array);
            });

            return(RetriveIntensityFiguresFromTextureArray(outIntensitiesNativeArray, generatedGrassTypes,
                                                           outFigureSize));
        }