示例#1
0
        internal static void SaveImageFile(string filename, TerrainOutputImage terrainOutput)
        {
            Helpers.Instance.SaveImageFile(filename, terrainOutput.ImageData);

            terrainOutput.ImageData = null;
            terrainOutput.ImagePath = filename;
        }
示例#2
0
        private static TerrainOutputImage splitTerrainSegments(GeoPoint[][] heightMap)
        {
            TerrainOutputImage terrainOutputSegments = new TerrainOutputImage();

            terrainOutputSegments.Title = "Segments";
            terrainOutputSegments.Key   = "segments";


            int[][] splittedTerrainSegments = new int[heightMap.Length][];
            float   maxHeight = 0;

            for (int x = 0; x < heightMap.Length; x++)
            {
                splittedTerrainSegments[x] = new int[heightMap[x].Length];
                for (int y = 0; y < heightMap[x].Length; y++)
                {
                    if (heightMap[x][y].Height > maxHeight)
                    {
                        maxHeight = heightMap[x][y].Height;
                    }
                }
            }

            float snowThreshold = 0.6f * maxHeight;

            for (int x = 0; x < heightMap.Length; x++)
            {
                for (int y = 0; y < heightMap[x].Length; y++)
                {
                    float           inclination = 0;
                    List <GeoPoint> neighbours  = GeoPoint.getAdjacentCells(heightMap, heightMap[x][y]);

                    float higherNeighbour = 0;
                    int   higherCount     = 0;
                    foreach (GeoPoint geoPoint in neighbours)
                    {
                        if (geoPoint.Height > heightMap[x][y].Height)
                        {
                            higherNeighbour += geoPoint.Height;
                            higherCount++;
                        }
                    }
                    higherNeighbour = higherNeighbour / (float)higherCount;

                    if (higherNeighbour != 0)
                    {
                        inclination = Math.Abs(heightMap[x][y].Height - higherNeighbour);
                    }

                    if (inclination > 0.02f)
                    {
                        //is rock
                        splittedTerrainSegments[x][y] = (0xff << 24) | (0x00 << 16) | (0x00 << 8) | 0xff;
                        heightMap[x][y].Type          = CellType.Rock;
                    }
                    else if (heightMap[x][y].Height > snowThreshold)
                    {
                        //is snow
                        splittedTerrainSegments[x][y] = (0xff << 24) | (0xff << 16) | (0xff << 8) | 0xff;
                        heightMap[x][y].Type          = CellType.Snow;
                    }
                    else
                    {
                        //is grass
                        splittedTerrainSegments[x][y] = (0x00 << 24) | (0xff << 16) | (0x00 << 8) | 0xff;
                        heightMap[x][y].Type          = CellType.Grass;
                    }
                }
            }

            terrainOutputSegments.ImageData = splittedTerrainSegments;
            return(terrainOutputSegments);
        }
示例#3
0
        public static void startWork(List <TerrainInput> terrainInputs, List <TerrainOutput> terrainOutputs, HeightmapWorkflowData heightmapWorkflowData)
        {
            int size = 513;
            Dictionary <string, TerrainInput> inputMap      = new Dictionary <string, TerrainInput>();
            Dictionary <string, FormField>    formFieldsMap = new Dictionary <string, FormField>();

            createInputMap(terrainInputs, inputMap, formFieldsMap);

            System.Console.Out.WriteLine("Starting");

            switch (((FormFieldOptions)formFieldsMap["parameters_gridSize"]).Value)
            {
            case 0:
                size = 65;
                break;

            case 1:
                size = 129;
                break;

            case 2:
                size = 257;
                break;

            case 3:
                size = 513;
                break;

            case 4:
                size = 1025;
                break;
            }

            Random random;

            if (targetSamples > 0)
            {
                random = new Random();
                if (curSample == 0)
                {
                    meanHeight   = new List <float>();
                    meanVariance = new List <float>();
                }
            }
            else
            {
                random = new Random(((FormFieldInteger)formFieldsMap["parameters_seed"]).Value);
            }
            //Random random = new Random(((FormFieldInteger)formFieldsMap["parameters_seed"]).Value);

            float heightFactor = (float)((FormFieldInteger)formFieldsMap["parameters_maxHeight"]).Value / (float)((FormFieldInteger)formFieldsMap["parameters_cellSize"]).Value;

            float?[][] heightMap = new float?[size][];

            for (int x = 0; x < heightMap.Length; x++)
            {
                heightMap[x] = new float?[size];
                for (int y = 0; y < heightMap.Length; y++)
                {
                    heightMap[x][y] = null;
                }
            }
            System.Console.Out.WriteLine("Data created");

            TerrainOutputImage terrainOutputRidges = new TerrainOutputImage();

            terrainOutputRidges.Title = "Ridges";
            terrainOutputRidges.Key   = "ridges";

            List <List <GeoPoint> > ridges = new List <List <GeoPoint> >();

            if (((FormFieldCheck)formFieldsMap["parameters_useRidgeSketch"]).Value)
            {
                int[][] resizedPixels = Helpers.Instance.ResizePixels(((TerrainInputSketch)inputMap["ridgeSketch"]).Value, ((TerrainInputSketch)inputMap["ridgeSketch"]).Width, ((TerrainInputSketch)inputMap["ridgeSketch"]).Height, size, size);

                terrainOutputRidges.ImageData = resizedPixels;

                for (int x = 0; x < heightMap.Length; x++)
                {
                    for (int y = 0; y < heightMap.Length; y++)
                    {
                        float height = (float)(((resizedPixels[x][y] & 0xff000000) >> 24) / 256.0);
                        if (height != 0)
                        {
                            heightMap[x][y] = height;
                        }
                    }
                }
            }
            else
            {
                int ridgeParticles = ((FormFieldInteger)formFieldsMap["parameters_ridgeParticles"]).Value;

                RidgeHelpers.createRidges(heightMap, ridges, random, ridgeParticles);

                terrainOutputRidges.ImageData = new int[heightMap.Length][];
                for (int x = 0; x < heightMap.Length; x++)
                {
                    terrainOutputRidges.ImageData[x] = new int[heightMap.Length];
                    for (int y = 0; y < heightMap[x].Length; y++)
                    {
                        byte color = 0;
                        if (heightMap[x][y] != null)
                        {
                            color = (byte)(heightMap[x][y] * 256);
                        }

                        terrainOutputRidges.ImageData[x][y] = (color << 24) | (color << 16) | (color << 8) | 0xff;
                    }
                }
            }


            GeoPoint[][]       gaussGeoPoints = TerrainHelpers.calculateDistanceToRidges(heightMap);
            TerrainOutputImage gaussTerrainOutputHeightMap = new TerrainOutputImage();

            gaussTerrainOutputHeightMap.Title = "Gauss Height map";
            gaussTerrainOutputHeightMap.Key   = "gaussHeightMap";

            gaussTerrainOutputHeightMap.ImageData = new int[gaussGeoPoints.Length][];
            for (int x = 0; x < gaussGeoPoints.Length; x++)
            {
                gaussTerrainOutputHeightMap.ImageData[x] = new int[gaussGeoPoints.Length];
                for (int y = 0; y < gaussGeoPoints[x].Length; y++)
                {
                    byte color = (byte)(gaussGeoPoints[x][y].Height * 256);
                    gaussTerrainOutputHeightMap.ImageData[x][y] = (color << 24) | (color << 16) | (color << 8) | 0xff;
                }
            }

            float?[][] gaussHeightMap = new float?[gaussGeoPoints.Length][];
            for (int x = 0; x < gaussGeoPoints.Length; x++)
            {
                gaussHeightMap[x] = new float?[gaussGeoPoints.Length];
                for (int y = 0; y < gaussGeoPoints[x].Length; y++)
                {
                    gaussHeightMap[x][y] = gaussGeoPoints[x][y].Height;
                }
            }

            int[][]   roughnessSketch = Helpers.Instance.ResizePixels(((TerrainInputSketch)inputMap["roughnessSketch"]).Value, ((TerrainInputSketch)inputMap["roughnessSketch"]).Width, ((TerrainInputSketch)inputMap["roughnessSketch"]).Height, size, size);
            float[][] roughness       = new float[size][];

            int veryLowColor  = ColorToInt(stringToColor("#0000ffff"));
            int lowColor      = ColorToInt(stringToColor("#00ffffff"));
            int highColor     = ColorToInt(stringToColor("#ffff00ff"));
            int veryHighColor = ColorToInt(stringToColor("#ff0000ff"));

            for (int x = 0; x < size; x++)
            {
                roughness[x] = new float[size];
                for (int y = 0; y < size; y++)
                {
                    if (roughnessSketch[x][y] == veryLowColor)
                    {
                        roughness[x][y] = 0.5f;
                    }
                    else if (roughnessSketch[x][y] == lowColor)
                    {
                        roughness[x][y] = 0.75f;
                    }
                    else if (roughnessSketch[x][y] == highColor)
                    {
                        roughness[x][y] = 1.25f;
                    }
                    else if (roughnessSketch[x][y] == veryHighColor)
                    {
                        roughness[x][y] = 1.5f;
                    }
                    else
                    {
                        roughness[x][y] = 1f;
                    }
                }
            }



            TerrainOutputImage terrainOutputRoughness = new TerrainOutputImage();

            terrainOutputRoughness.Title     = "Roughness";
            terrainOutputRoughness.Key       = "roughness";
            terrainOutputRoughness.ImageData = roughnessSketch;


            //List<GeoPoint> riverPoints = RiverHelpers.traceRivers(gaussHeightMap, ridges, 8, random);

            /*foreach(GeoPoint geoPoint in riverPoints)
             * {
             *  heightMap[geoPoint.X][geoPoint.Y] = geoPoint.Height;
             * }*/
            List <GeoPoint> riverPoints = new List <GeoPoint>();

            System.Console.Out.WriteLine("Ridges created");
            TerrainHelpers.generateTerrain(heightMap, random, roughness, riverPoints, gaussHeightMap);
            System.Console.Out.WriteLine("Terrain created");

            int termalErosionPass = ((FormFieldInteger)formFieldsMap["parameters_thermalErosionPass"]).Value;

            if (termalErosionPass != 0)
            {
                ErosionHelpers.applyThermalErosion(heightMap, termalErosionPass);
                System.Console.Out.WriteLine("ThermalErosion applied");
            }

            int hydraulicErosionPass = ((FormFieldInteger)formFieldsMap["parameters_hydraulicErosionPass"]).Value;

            if (hydraulicErosionPass != 0)
            {
                HydraulicErosionCell[][] hydraulicErosionCells = ErosionHelpers.applyHydraulicErosion(heightMap, hydraulicErosionPass);
                System.Console.Out.WriteLine("HydraulicErosion applied");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("###Pass " + hydraulicErosionPass + "######");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
                System.Console.Out.WriteLine("########################");
            }

            System.Console.Out.WriteLine("##From terrain changed!!!");



            String meanHeightStr   = "Mean samples: ";
            String meanVarianceStr = "Mean variance: ";


            Boolean doContinue = true;

            if (targetSamples > 0)
            {
                //meanHeight = new List<float>();
                //meanVariance = new List<float>();

                int    count   = 0;
                double sum     = 0;
                double diffSum = 0;
                for (int x = 0; x < heightMap.Length; x++)
                {
                    for (int y = 0; y < heightMap[x].Length; y++)
                    {
                        count++;
                        sum += heightMap[x][y].Value;

                        diffSum += Math.Abs(getAdjacentCellsMean(heightMap, x, y).Value - heightMap[x][y].Value);
                    }
                }

                float mean     = (float)(sum / count);
                float diffMean = (float)(diffSum / count);

                meanHeight.Add(mean);
                meanVariance.Add(diffMean);

                foreach (float meanValue in meanHeight)
                {
                    meanHeightStr += "#" + meanValue;
                }

                foreach (float varianceValue in meanVariance)
                {
                    meanVarianceStr += "#" + varianceValue;
                }

                System.Console.Out.WriteLine(meanHeightStr);
                System.Console.Out.WriteLine(meanVarianceStr);

                curSample++;

                if (curSample < targetSamples)
                {
                    terrainOutputs.Clear();

                    System.Console.Out.WriteLine("Starting sample:" + curSample);
                    doContinue = false;
                    startWork(terrainInputs, terrainOutputs, heightmapWorkflowData);
                }
                else
                {
                    System.Console.Out.WriteLine("All samples done");
                }
            }



            if (!doContinue)
            {
                return;
            }



            TerrainOutputMesh terrainOutputMesh = new TerrainOutputMesh();

            terrainOutputMesh.Title          = "Height map mesh";
            terrainOutputMesh.Key            = "heightMap";
            terrainOutputMesh.CameraPosition = new float[] { 0, size / 4, 0 };
            terrainOutputMesh.CameraRotation = new float[] { 22.5f, 45, 0 };

            exportHeightMap(heightMap, terrainOutputMesh, heightFactor);


            TerrainOutputImage terrainOutputHeightMap = new TerrainOutputImage();

            terrainOutputHeightMap.Title = "Height map bmp";
            terrainOutputHeightMap.Key   = "heightMapBmp";

            GeoPoint[][] heightMapGeoPoints = new GeoPoint[heightMap.Length][];

            terrainOutputHeightMap.ImageData     = new int[heightMap.Length][];
            heightmapWorkflowData.HeightmapCells = new float[heightMap.Length][];
            float maxHeight = 0;
            float minHeight = 1;

            for (int x = 0; x < heightMap.Length; x++)
            {
                heightMapGeoPoints[x] = new GeoPoint[heightMap[x].Length];
                terrainOutputHeightMap.ImageData[x]     = new int[heightMap.Length];
                heightmapWorkflowData.HeightmapCells[x] = new float[heightMap.Length];
                for (int y = 0; y < heightMap[x].Length; y++)
                {
                    GeoPoint geoPoint = new GeoPoint();
                    geoPoint.Height          = (float)heightMap[x][y];
                    geoPoint.X               = x;
                    geoPoint.Y               = y;
                    heightMapGeoPoints[x][y] = geoPoint;
                    byte color = (byte)(heightMap[x][y] * 256);
                    terrainOutputHeightMap.ImageData[x][y]     = (color << 24) | (color << 16) | (color << 8) | 0xff;
                    heightmapWorkflowData.HeightmapCells[x][y] = (float)heightMap[x][y];

                    if (maxHeight < (float)heightMap[x][y])
                    {
                        maxHeight = (float)heightMap[x][y];
                    }

                    if (minHeight > (float)heightMap[x][y])
                    {
                        minHeight = (float)heightMap[x][y];
                    }
                }
            }

            heightmapWorkflowData.MaxHeight = maxHeight * (float)((FormFieldInteger)formFieldsMap["parameters_maxHeight"]).Value;
            heightmapWorkflowData.MinHeight = minHeight * (float)((FormFieldInteger)formFieldsMap["parameters_maxHeight"]).Value;
            heightmapWorkflowData.CellSize  = (float)((FormFieldInteger)formFieldsMap["parameters_cellSize"]).Value;

            foreach (GeoPoint geoPoint in riverPoints)
            {
                byte color = (byte)(geoPoint.Height * 256);
                terrainOutputHeightMap.ImageData[geoPoint.X][geoPoint.Y] = (0x00 << 24) | (0x00 << 16) | (color << 8) | 0xff;
            }



            int chunk = 0;
            TerrainOutputMesh splittedMesh = new TerrainOutputMesh();

            splittedMesh.Title = "Terrain";
            splittedMesh.Key   = "terrainHeightMap";

            List <float[]> grassLand = new List <float[]>();

            MeshGeneratorHelpers.FillHeightMapMesh(splittedMesh, heightMapGeoPoints, heightmapWorkflowData.CellSize, heightmapWorkflowData.MinHeight, heightmapWorkflowData.MaxHeight, grassLand);


            /*splittedMesh.VertexData.Add(new List<float[]>());
             * splittedMesh.FacesData.Add(new List<int[]>());
             * splittedMesh.MaterialColor.Add("#ffffffff");
             * splittedMesh.MaterialTexture.Add("HeightMapMaterials\\transitionTexture.png");
             * splittedMesh.TexureCoordData.Add(new List<float[]>());
             * exportTransitionHeightMap(heightMapGeoPoints, splittedMesh, chunk, heightFactor);*/



            terrainOutputs.Add(splittedMesh);
            //terrainOutputs.Add(terrainOutputMesh);
            terrainOutputs.Add(terrainOutputHeightMap);
            terrainOutputs.Add(gaussTerrainOutputHeightMap);
            terrainOutputs.Add(terrainOutputRidges);
            //terrainOutputs.Add(terrainOutputObject);
            //terrainOutputs.Add(terrainOutputRoughness);
            //terrainOutputs.Add(terrainOutputSplitted);

            //Vector[][] waterVelocityField = RiverHelpers.getVelocityField(gaussHeightMap);
            //terrainOutputs.Add(RiverHelpers.getVectorFieldImage(waterVelocityField));
        }