コード例 #1
0
        public static Bitmap GenerateCompositeMap(HeightData data, Bitmap baseMap, float heightmapIntensity, float hillshadeIntensity)
        {
            Bitmap result;

            if (baseMap == null)
            {
                result = new Bitmap(data.GridWidth, data.GridHeight);
                var graphics = Graphics.FromImage(result);
                graphics.FillRectangle(new SolidBrush(Color.Gray), new Rectangle(0, 0, baseMap.Width, baseMap.Height));
            }
            else
            {
                result = baseMap;
            }
            if (heightmapIntensity > 0)
            {
                Bitmap hm = new ImageGenerator(data.GetDataGrid(), data.cellSize, ImageType.Heightmap, data.lowPoint, data.highPoint).image;
                result = OverlayBlend(result, hm, heightmapIntensity);
            }
            if (hillshadeIntensity > 0)
            {
                Bitmap hs = new ImageGenerator(data.GetDataGrid(), data.cellSize, ImageType.Hillshade, data.lowPoint, data.highPoint).image;
                result = OverlayBlend(result, hs, hillshadeIntensity);
            }
            return(result);
        }
コード例 #2
0
ファイル: OutputManager.cs プロジェクト: polytronicgr/geogen
        // preserves 0 level!!!
        public static void StretchHeightValues(ref HeightData data)
        {
            // find minimum and maximum values
            short max = short.MinValue;
            short min = short.MaxValue;

            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] > max)
                {
                    max = data[i];
                }
                if (data[i] < min)
                {
                    min = data[i];
                }
            }

            // is the ocean deeper than land is high?
            if (max < -min)
            {
                max = (short)-min;
            }

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = max > 0 ? (short)((int)data[i] * (int)short.MaxValue / (int)max) : (short)0;
            }
        }
コード例 #3
0
        public void TestMCAAccuracy()
        {
            var        heights = HeightmapImporter.ImportHeightmapRaw(Path.Combine(inputPath, sampleHeightmapFile), 0, 0, 512, 512);
            HeightData data    = new HeightData(512, 512, null)
            {
                lowPoint  = 0,
                highPoint = 255
            };

            for (int i = 0; i < 512; i++)
            {
                for (int j = 0; j < 512; j++)
                {
                    data.SetHeight(i, j, heights[i, j]);
                }
            }
            var    sampleLocations = GetSampleLocations(data.GridWidth, data.GridHeight);
            var    sourceSamples   = GetHeightSamples(data, sampleLocations);
            string mcaname         = "accuracy-test-r.0.0.mca";

            AssertExport(data, "MCR-RAW", mcaname);
            var reimported  = ImportManager.ImportFile(Path.Combine(outputPath, mcaname));
            var convSamples = GetHeightSamples(reimported, sampleLocations);

            AssertExport(data, "IMG_PNG-HM", "reconstructed_mca.png");
            Assert.AreEqual(sourceSamples, convSamples);
        }
コード例 #4
0
ファイル: OutputManager.cs プロジェクト: polytronicgr/geogen
        public static void ScaleHeightValues(ref HeightData data, short newMin, short newMax)
        {
            // find minimum and maximum values
            int max = short.MinValue;
            int min = short.MaxValue;

            int newMaxWork = newMax - newMin;

            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] > max)
                {
                    max = data[i];
                }
                if (data[i] < min)
                {
                    min = data[i];
                }
            }

            max -= min;

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (short)((short)newMin + (short)(((int)data[i] - min) * newMaxWork / max));
            }
        }
コード例 #5
0
ファイル: ResizingModifier.cs プロジェクト: D3TONAT0R/HMCon
 protected override void ModifyData(HeightData data)
 {
     if (newWidth > 0)
     {
         data.Resize(newWidth, adjustHeight);
     }
 }
コード例 #6
0
ファイル: Bounds.cs プロジェクト: D3TONAT0R/HMCon
 public bool IsValid(HeightData d)
 {
     if (xMin < 0 || xMin >= d.GridWidth)
     {
         return(false);
     }
     if (yMin < 0 || yMin >= d.GridHeight)
     {
         return(false);
     }
     if (xMax < 0 || xMax >= d.GridWidth)
     {
         return(false);
     }
     if (yMax < 0 || yMax >= d.GridHeight)
     {
         return(false);
     }
     if (xMin > xMax)
     {
         return(false);
     }
     if (yMin > yMax)
     {
         return(false);
     }
     return(true);
 }
コード例 #7
0
        public HeightData Modify(HeightData inputData, bool keepOriginal)
        {
            HeightData data = keepOriginal ? new HeightData(inputData) : inputData;

            ModifyData(data);
            return(data);
        }
コード例 #8
0
ファイル: OutputManager.cs プロジェクト: polytronicgr/geogen
        public static System.Drawing.Bitmap HeightDataToBitmap(HeightData data)
        {
            // create a blank bitmap
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(data.Width, data.Height);

            // lock the bitmap color data for byte access
            System.Drawing.Rectangle          rect   = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
            System.Drawing.Imaging.BitmapData locked = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat);

            // prepare memory space for the new color data
            byte[] bytes = new byte[locked.Stride * bitmap.Height];

            // get a pointer to the to first line (=first pixel)
            IntPtr ptr = locked.Scan0;

            // fill in the bytes
            for (int i = 0; i < bytes.Length; i += 4)
            {
                // we won't be able to display the height data lower than 0 -> crop them
                byte current = (byte)(data[i / 4] > 0 ? (data[i / 4] / 128) : 0);

                bytes[i + 0] = current;
                bytes[i + 1] = current;
                bytes[i + 2] = current;
                bytes[i + 3] = 255;
            }

            // copy the data into the bitmap
            System.Runtime.InteropServices.Marshal.Copy(bytes, 0, ptr, locked.Stride * bitmap.Height);

            // unlock the bits
            bitmap.UnlockBits(locked);

            return(bitmap);
        }
コード例 #9
0
        public static HeightData ImportHeightmap(string filepath, HeightmapType type)
        {
            ushort[,] hms = RegionImporter.GetHeightmap(filepath, type);
            HeightData asc = new HeightData(512, 512, filepath);

            for (int x = 0; x < 512; x++)
            {
                for (int z = 0; z < 512; z++)
                {
                    asc.SetHeight(x, z, hms[x, 511 - z]);
                }
            }
            asc.filename     = Path.GetFileNameWithoutExtension(filepath);
            asc.cellSize     = 1;
            asc.nodata_value = -9999;
            asc.RecalculateValues(false);
            asc.lowPoint  = 0;
            asc.highPoint = 255;
            asc.isValid   = true;
            ConsoleOutput.WriteLine("Lowest: " + asc.lowestValue);
            ConsoleOutput.WriteLine("Hightest: " + asc.highestValue);
            asc.lowestValue  = 0;
            asc.highestValue = 255;
            return(asc);
        }
コード例 #10
0
        bool WriteFileImage(HeightData source, string filename, FileFormat ff)
        {
            float[,] grid = source.GetDataGrid();
            IExporter exporter = new ImageGenerator(grid, source.cellSize, ff.GetImageType(), source.lowPoint, source.highPoint);

            ExportUtility.WriteFile(exporter, filename, ff);
            return(true);
        }
コード例 #11
0
    private void SaveDataHeight()
    {
        HeightData d = new HeightData();

        d.blurHeight = blurHeight.vars;
        d.heightmap  = heightmap.vars;
        WriteParams(d, assetName, "Height.xml");
    }
コード例 #12
0
 void Start()
 {
     sa = StartActions.GetStartActions();
     if (sa == null)
     {
         Debug.LogError("EdgeTrigger: Startaction is null!");
     }
     highData = transform.GetComponent <HeightData>();
 }
コード例 #13
0
ファイル: OutputManager.cs プロジェクト: polytronicgr/geogen
        public void ExportData()
        {
            Config config = this.GetConfig();

            Export export = new Export();

            export.width.Maximum  = this.heightData.Width;
            export.width.Value    = this.heightData.Width;
            export.height.Maximum = this.heightData.Height;
            export.height.Value   = this.heightData.Height;
            if (config.exportRescaleMode)
            {
                export.subzeroMode2.Checked = true;
            }

            if (export.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (this.FileDialog(this.exportHeightmapDialog, ref config.lastExportedFile))
                {
                    string path = this.exportHeightmapDialog.FileName;
                    string ext  = path.Substring(path.LastIndexOf('.'), path.Length - path.LastIndexOf('.')).ToLower();

                    //config.lastExportedFile = path;

                    config.exportRescaleMode = export.subzeroMode2.Checked;

                    HeightData toExport = Main.GetResizedHeightData(this.heightData, (int)export.width.Value, (int)export.height.Value);

                    // rescale the values if necessary
                    if (ext != ".shd" && export.subzeroMode2.Checked)
                    {
                        Main.ScaleHeightValues(ref toExport, 0, short.MaxValue - 1);
                    }

                    if (ext == ".shd")
                    {
                        System.IO.BinaryWriter writer = new System.IO.BinaryWriter(System.IO.File.Open(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write));
                        writer.Write(toExport.Width);
                        writer.Write(toExport.Height);

                        for (int i = 0; i < toExport.Length; i++)
                        {
                            writer.Write(toExport[i]);
                        }

                        writer.Close();
                    }
                    else
                    {
                        Main.HeightDataToBitmap(toExport).Save(path);
                    }

                    toExport.Dispose();
                }
            }
        }
コード例 #14
0
        void ExportFile(HeightData data, string outPath)
        {
            try {
                string dir   = Path.GetDirectoryName(outPath);
                string fname = Path.GetFileNameWithoutExtension(outPath);
                if (Directory.Exists(dir))
                {
                    HeightDataSplitter splitter = new HeightDataSplitter(data, exportSettings.fileSplitDims);
                    for (int z = 0; z < splitter.NumDataY; z++)
                    {
                        for (int x = 0; x < splitter.NumDataX; x++)
                        {
                            exportNumX = x;
                            exportNumZ = z;
                            foreach (FileFormat format in exportSettings.outputFormats)
                            {
                                ExportJob exportJob = new ExportJob(splitter.GetDataChunk(x, z), format, exportSettings, dir, fname);
                                if (splitter.NumChunks > 1)
                                {
                                    exportJob.nameBuilder.gridNum = (x, z);
                                }
                                format.exportHandler.EditFileName(exportJob, exportJob.nameBuilder);
                                string fullpath = exportJob.nameBuilder.GetFullPath();

                                WriteLine($"Creating file {fullpath} ...");
                                try {
                                    var startTime = DateTime.Now;
                                    exportJob.Export();
                                    var span = DateTime.Now - startTime;
                                    if (span.TotalSeconds > 5)
                                    {
                                        WriteLine($"Time: {span.TotalSeconds:F2}");
                                    }
                                    WriteSuccess($"{format.Identifier} file created successfully!");
                                } catch (Exception e) {
                                    throw new IOException($"Failed to write {format.Identifier} file!", e);
                                }
                            }
                        }
                    }
                }
                else
                {
                    throw new IOException($"Directory '{dir}' does not exist!");
                }
                if (FileExported != null)
                {
                    FileExported(CurrentFileIndex, outputPath);
                }
            } catch (Exception e) {
                if (FileExportFailed != null)
                {
                    FileExportFailed(CurrentFileIndex, outputPath, e);
                }
            }
        }
コード例 #15
0
        public static bool ValidateExportSettings(ExportSettings settings, HeightData data, FileFormat ff)
        {
            bool valid = true;

            foreach (var ex in exportHandlers)
            {
                valid &= ex.AreExportSettingsValid(settings, ff, data);
            }
            return(valid);
        }
コード例 #16
0
        void AssertExport(HeightData data, string filetype, string path)
        {
            var format = ExportUtility.GetFormatFromIdenfifier(filetype);

            path = Path.ChangeExtension(Path.Combine(outputPath, path), format.Extension);
            var job = new ExportJob(data, format, new ExportSettings(), outputPath, path);

            job.Export();
            Assert.IsTrue(File.Exists(path), "Written file not found");
        }
コード例 #17
0
        public float QueryHeightData(float x, float y)
        {
            if (HeightData != null)
            {
                return(Conversions.GetRelativeHeightFromColor(HeightData.GetPixel(
                                                                  (int)Mathf.Clamp((x * 256), 0, 255),
                                                                  (int)Mathf.Clamp((y * 256), 0, 255)), RelativeScale));
            }

            return(0);
        }
コード例 #18
0
ファイル: ExportJob.cs プロジェクト: D3TONAT0R/HMCon
 public ExportJob(HeightData heightData, FileFormat fileFormat, ExportSettings exportSettings, string targetDirectory, string filename)
 {
     data     = heightData;
     settings = exportSettings;
     format   = fileFormat;
     if (Path.GetExtension(filename).Equals("." + fileFormat.Extension, StringComparison.OrdinalIgnoreCase))
     {
         filename = filename.Substring(0, filename.Length - 1 - fileFormat.Extension.Length);
     }
     nameBuilder = new FileNameBuilder(targetDirectory, filename, fileFormat);
 }
コード例 #19
0
        public void TestASCExport()
        {
            HeightData data            = ASCImporter.Import(Path.Combine(inputPath, sampleASCFile));
            var        sampleLocations = GetSampleLocations(data.GridWidth, data.GridHeight);
            var        sourceSamples   = GetHeightSamples(data, sampleLocations);

            AssertExport(data, "ASC", sampleASCFile);
            data = ASCImporter.Import(Path.Combine(outputPath, sampleASCFile));
            var exportedSamples = GetHeightSamples(data, sampleLocations);

            Assert.AreEqual(sourceSamples, exportedSamples);
        }
コード例 #20
0
        public void ClearData3D()
        {
            this.Output3dButtonsOff();

            // terminate the model calculation worker thread
            if (this.modelThread != null)
            {
                this.modelThread.Abort();

                this.HideBuildingModel();
            }

            // release the height data
            if(this.heightData != null) this.heightData.Dispose();
            if (this.textureBase != null) this.textureBase.Dispose();
            this.heightData = null;
            this.textureBase = null;

            this.outputs3d.Items.Clear();

            // remove "Maps:" entries from the texture list
            for (int i = 0; i < this.texture.Items.Count; i++)
            {
                char c = ((string)this.texture.Items[i])[0];

                if (((string)this.texture.Items[i])[0] == 'M')
                {
                    this.texture.Items.RemoveAt(i);
                    
                    // the indexes got shifted by deleting the current item
                    i--;
                }
            }

            // free Video-RAM
            if (this.vertexBufferHandle != 0)
            {
                GL.DeleteBuffers(1, ref this.vertexBufferHandle);
                GL.DeleteBuffers(1, ref this.indexBufferHandle);
            }

            if (this.textureHandle != 0)
            {
                GL.DeleteTexture(this.textureHandle);
            }

            this.vertexBufferHandle = 0;
            this.textureHandle = 0;

            // let the viewport show empty screen
            this.viewport.Invalidate();
        }
コード例 #21
0
        public void Execute(int i)
        {
            int x, z;

            Utils.IndexDeflattenizer2D(i, TotalBlockNumberX, out x, out z);

            Result[i] = new HeightData()
            {
                Bedrock = GenerateBedrockHeight(x, z),
                Stone   = GenerateStoneHeight(x, z),
                Dirt    = GenerateDirtHeight(x, z)
            };
        }
コード例 #22
0
 protected override void ModifyData(HeightData data)
 {
     if (newLow == 0 && newHigh == 0)
     {
         data.RecalculateValues(true);
     }
     else
     {
         data.lowPoint  = newLow;
         data.highPoint = newHigh;
         data.RecalculateValues(false);
     }
 }
コード例 #23
0
        public HeightData ApplyModificationChain(HeightData inputData)
        {
            HeightData data = new HeightData(inputData)
            {
                wasModified = true
            };

            for (int i = 0; i < exportSettings.modificationChain.Count; i++)
            {
                data = exportSettings.modificationChain[i].Modify(data, true);
            }
            return(data);
        }
コード例 #24
0
 protected override void ModifyData(HeightData data)
 {
     for (int y = 0; y < data.GridHeight; y++)
     {
         for (int x = 0; x < data.GridWidth; x++)
         {
             var value = data.GetHeight(x, y);
             value = (value - scalePivot) * scaleMultiplier + scalePivot;
             data.SetHeight(x, y, value);
         }
     }
     data.RecalculateValues(true);
 }
コード例 #25
0
ファイル: RichCell.cs プロジェクト: andrewstarnes/wwtd2
        /// <summary>
        /// Initializes a new instance of the <see cref="RichCell"/> class.
        /// </summary>
        /// <param name="parent">The cell matrix that owns this cell.</param>
        /// <param name="position">The position.</param>
        /// <param name="matrixPosX">The matrix position x.</param>
        /// <param name="matrixPosZ">The matrix position z.</param>
        /// <param name="blocked">if set to <c>true</c> the cell will appear permanently blocked.</param>
        public RichCell(CellMatrix parent, Vector3 position, int matrixPosX, int matrixPosZ, bool blocked)
            : base(parent, position, matrixPosX, matrixPosZ, blocked)
        {
            //While a bit redundant (e.g. index 4 being self) it makes it faster to index
            _heightData = new HeightData[9];
            for (int i = 0; i < 9; i++)
            {
                //We use this to indicate an uninitialized state
                _heightData[i].slope = 100f;
            }

            //Worst case scenario for checking all directions
            _worstCase = new HeightData();
        }
コード例 #26
0
ファイル: RichCell.cs プロジェクト: forwolk/UnityApex
        public RichCell(CellMatrix parent, Vector3 position, int matrixPosX, int matrixPosZ, bool blocked)
            : base(parent, position, matrixPosX, matrixPosZ, blocked)
        {
            //While a bit redundant (e.g. index 4 being self) it makes it faster to index
            _heightData = new HeightData[9];
            for (int i = 0; i < 9; i++)
            {
                //We use this to indicate an uninitialized state
                _heightData[i].slope = 100f;
            }

            //Worst case scenario for checking all directions
            _worstCase = new HeightData();
        }
コード例 #27
0
 private void LoadDataHeight()
 {
     if (File.Exists(GetSavePath(assetName) + "Height.xml"))
     {
         HeightData d = ReadParams <HeightData>(assetName, "Height.xml");
         blurHeight.SetPara(d.blurHeight);
         heightmap.SetPara(d.heightmap);
     }
     else
     {
         blurHeight.ResetPara();
         heightmap.ResetPara();
     }
 }
コード例 #28
0
ファイル: HeightDataSplitter.cs プロジェクト: D3TONAT0R/HMCon
 public HeightDataSplitter(HeightData data, int splitIntervalX, int splitIntervalY)
 {
     intervalX = splitIntervalX;
     intervalY = splitIntervalY;
     if (intervalX < 2)
     {
         intervalX = int.MaxValue;
     }
     if (intervalY < 2)
     {
         intervalY = int.MaxValue;
     }
     sourceData = data;
 }
コード例 #29
0
ファイル: ASCImporter.cs プロジェクト: D3TONAT0R/HMCon
        static HeightData CreateBaseData(FileStream stream, string filename, out int ncols, out int nrows)
        {
            ncols = ExtractInt(ReadHeaderLine(stream), "ncols");
            nrows = ExtractInt(ReadHeaderLine(stream), "nrows");
            WriteLine("Dimensions: " + ncols + "x" + nrows);
            HeightData d         = new HeightData(ncols, nrows, filename);
            var        xllcorner = ExtractFloat(ReadHeaderLine(stream), "xllcorner");
            var        yllcorner = ExtractFloat(ReadHeaderLine(stream), "yllcorner");

            d.lowerCornerPos = new Vector2(xllcorner, yllcorner);
            d.cellSize       = ExtractFloat(ReadHeaderLine(stream), "cellsize");
            d.nodata_value   = ExtractFloat(ReadHeaderLine(stream), "NODATA_value");
            return(d);
        }
コード例 #30
0
        public void TestMCAFileHandling()
        {
            HeightData data = ImportManager.ImportFile(Path.Combine(inputPath, sampleMCAFile));

            data.lowPoint  = 0;
            data.highPoint = 255;
            //var sampleLocations = GetSampleLocations(data.GridWidth, data.GridHeight);
            //var sourceSamples = GetHeightSamples(data, sampleLocations);
            currentJob.exportSettings.SetCustomSetting("mcaOffsetX", 16);
            currentJob.exportSettings.SetCustomSetting("mcaOffsetZ", 26);
            AssertExport(data, "MCR", sampleMCAFile);
            AssertExport(data, "IMG_PNG-HS", sampleMCAFile);
            AssertExport(data, "IMG_PNG-HM", sampleMCAFile);
        }
コード例 #31
0
    static BlockTypes DetermineType(int worldX, int worldY, int worldZ, HeightData height)
    {
        if (worldY == 0)
        {
            return(BlockTypes.Bedrock);
        }

        // check if this suppose to be a cave
        if (FractalFunc(worldX, worldY, worldZ, CaveSmooth, CaveOctaves) < CaveProbability)
        {
            return(BlockTypes.Air);
        }

        // bedrock
        if (worldY <= height.Bedrock)
        {
            return(BlockTypes.Bedrock);
        }

        // stone
        if (worldY <= height.Stone)
        {
            if (FractalFunc(worldX, worldY, worldZ, DiamondSmooth, DiamondOctaves) < DiamondProbability &&
                worldY < DiamondMaxHeight)
            {
                return(BlockTypes.Diamond);
            }

            if (FractalFunc(worldX, worldY, worldZ, RedstoneSmooth, RedstoneOctaves) < RedstoneProbability &&
                worldY < RedstoneMaxHeight)
            {
                return(BlockTypes.Redstone);
            }

            return(BlockTypes.Stone);
        }

        // dirt
        if (worldY == height.Dirt)
        {
            return(BlockTypes.Grass);
        }
        if (worldY < height.Dirt)
        {
            return(BlockTypes.Dirt);
        }

        return(BlockTypes.Air);
    }
コード例 #32
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        public static HeightData LoadHeightmapFromImageFile(string path){
            Config config = Main.Get().GetConfig();
            
            HeightData heights;
            
            string ext = path.Substring(path.LastIndexOf('.'), path.Length - path.LastIndexOf('.')).ToLower();

            if (ext == ".shd")
            {
                // byte-by-byte binary reading
                System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.Open(path, System.IO.FileMode.Open, System.IO.FileAccess.Read));

                // read first eight bytes with map dimensions
                int width = reader.ReadInt32();
                int height = reader.ReadInt32();

                heights = new HeightData((UInt16) width,(UInt16) height);

                // read the double bytes containing the height data
                for (int i = 0; i < width * height; i++)
                {
                    heights[i] = reader.ReadInt16();
                }

                reader.Close();

                reader.Dispose();
            }
            else
            {
                // read the bitmap file


                System.Drawing.Bitmap bitmap;

                try
                {
                    bitmap = new System.Drawing.Bitmap(path);
                }
                catch(ArgumentException){
                    return null;
                }

                System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
                System.Drawing.Imaging.BitmapData data = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);

                heights = new HeightData((UInt16) bitmap.Width, (UInt16)bitmap.Height);

                // prepare memory space for the color data
                byte[] bytes = new byte[data.Stride * bitmap.Height];

                int pixelSize = data.Stride / data.Width;

                // get a pointer to the to first line (=first pixel)
                IntPtr ptr = data.Scan0;

                // create a byte copy of the heightmap data
                System.Runtime.InteropServices.Marshal.Copy(ptr, bytes, 0, data.Stride * bitmap.Height);

                // create the color data
                for (int i = 0; i < bytes.Length; i += pixelSize)
                {
                    heights[i / pixelSize] = (short)((short)bytes[i] * 128);
                }

                bitmap.UnlockBits(data);

                bitmap.Dispose();
            }

            HeightData heights2 = Main.GetResizedHeightData(heights, Math.Min(heights.Width, (int)config.mapDetailLevel), Math.Min(heights.Height, (int)config.mapDetailLevel));

            return heights2;
        }
コード例 #33
0
ファイル: RichCell.cs プロジェクト: forwolk/UnityApex
 internal void SetHeightData(int idx, HeightData data)
 {
     _heightData[idx] = data;
 }
コード例 #34
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        public void ShowImage()
        {
            Config config = this.GetConfig();

            try
            {
                this.AddStatus("Loading");

                int oldImageWidth = 0;
                int oldImageHeight = 0;

                // save original output image dimensions, so we can deetect their change
                if (this.output.Image != null)
                {
                    oldImageWidth = this.output.Image.Width;
                    oldImageHeight = this.output.Image.Height;
                }

                // if the image being loaded doesn't exist, cancel
                try
                {
                    // load imported or internal
                    if (this.currentImportedFile != null)
                    {
                        this.data = Main.LoadHeightmapFromImageFile(this.currentImportedFile);

                        if (this.data == null) throw new Exception();
                    }
                    else
                    {
                        this.data = (HeightData)this.maps[this.outputs.SelectedItem];
                    }
                    currentImage = HeightDataToBitmap(this.data);
                }
                catch (Exception e)
                {
                    this.RemoveStatus("Loading");

                    return;
                }


                // apply overlay pattern?
                if (this.overlays.SelectedIndex > 0)
                {
                    string overlayPath = config.OverlayDirectory + "/" + (string)this.overlays.Items[this.overlays.SelectedIndex];

                    System.Drawing.Bitmap overlay = new System.Drawing.Bitmap(overlayPath);
                    this.currentImageWithOverlay = this.ApplyOverlay(this.data, overlay);

                    overlay.Dispose();
                }

                // decide which image (gray or overlay) to display
                if (this.overlays.SelectedIndex > 0 && this.toggleOverlay.Checked)
                {
                    this.output.Image = this.currentImageWithOverlay;
                }
                else
                {
                    this.output.Image = this.currentImage;
                }

                // detect size change (reset the view if size changed to prevent the image shrinking avay from the screen)
                if (oldImageWidth > this.output.Image.Width || oldImageHeight > this.output.Image.Width || oldImageHeight == 0)
                {
                    this.output.Width = this.output.Image.Width;
                    this.output.Height = this.output.Image.Height;
                }
            }
            catch (OutOfMemoryException)
            {
                this.OutOfMemory();
            }

            this.RemoveStatus("Loading");
        }
コード例 #35
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        public static System.Drawing.Bitmap HeightDataToBitmap(HeightData data){
            // create a blank bitmap
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(data.Width, data.Height);

            // lock the bitmap color data for byte access
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
            System.Drawing.Imaging.BitmapData locked = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat);

            // prepare memory space for the new color data
            byte[] bytes = new byte[locked.Stride * bitmap.Height];

            // get a pointer to the to first line (=first pixel)
            IntPtr ptr = locked.Scan0;

            // fill in the bytes
            for (int i = 0; i < bytes.Length; i += 4)
            {
                // we won't be able to display the height data lower than 0 -> crop them
                byte current = (byte)(data[i / 4] > 0 ? (data[i / 4] / 128) : 0);

                bytes[i + 0] = current;
                bytes[i + 1] = current;
                bytes[i + 2] = current;
                bytes[i + 3] = 255;
            }

            // copy the data into the bitmap
            System.Runtime.InteropServices.Marshal.Copy(bytes, 0, ptr, locked.Stride * bitmap.Height);

            // unlock the bits
            bitmap.UnlockBits(locked);

            return bitmap;
        }
コード例 #36
0
ファイル: RichCell.cs プロジェクト: forwolk/UnityApex
        internal void SetHeightData(int dx, int dz, HeightData data)
        {
            var idx = (dx + (3 * dz) + 4);

            _heightData[idx] = data;
        }
コード例 #37
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        // preserves 0 level!!!
        public static void StretchHeightValues(ref HeightData data){
            // find minimum and maximum values
            short max = short.MinValue;
            short min = short.MaxValue;

            for(int i = 0; i < data.Length; i++){
                if(data[i] > max) max = data[i];
                if(data[i] < min) min = data[i];
            }

            // is the ocean deeper than land is high?
            if(max < -min) max = (short) -min;

            for (int i = 0; i < data.Length; i++){
                data[i] = max > 0 ? (short)((int)data[i] * (int)short.MaxValue / (int)max) : (short)0;
            }
        }
コード例 #38
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        public static void ScaleHeightValues(ref HeightData data, short newMin, short newMax)
        {
            // find minimum and maximum values
            int max = short.MinValue;
            int min = short.MaxValue;

            int newMaxWork = newMax - newMin;

            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] > max) max = data[i];
                if (data[i] < min) min = data[i];
            }

            max -= min;

            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (short)((short)newMin + (short)(((int)data[i] - min) * newMaxWork / max));
            }
        }
コード例 #39
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        public static HeightData GetResizedHeightData(HeightData data, int width, int height)
        {
            HeightData resized = new HeightData((UInt16)width, (UInt16)height);
            
            // use nearest neighbor scaling algorithm
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    resized[x, y] = data[x * data.Width / width, y * data.Height / height];
                }
            }

            return resized;
        }
コード例 #40
0
ファイル: OutputManager.cs プロジェクト: hamstah/geogen
        public System.Drawing.Bitmap ApplyOverlay(HeightData heights, System.Drawing.Bitmap overlayBitmap)
        {
            // prepare byte access to the overlay bitmap
            System.Drawing.Rectangle OverlayRect = new System.Drawing.Rectangle(0, 0, overlayBitmap.Width, overlayBitmap.Height);
            System.Drawing.Imaging.BitmapData overlayData = overlayBitmap.LockBits(OverlayRect, System.Drawing.Imaging.ImageLockMode.ReadOnly, overlayBitmap.PixelFormat);

            // create a blank bitmap and prepare it for byte access
            System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(heights.Width, heights.Height, overlayData.PixelFormat);
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
            System.Drawing.Imaging.BitmapData data = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, overlayBitmap.PixelFormat);

            // prepare memory space for the newly created color data
            byte[] bytes = new byte[data.Stride * bitmap.Height];
            byte[] overlayCopy = new byte[overlayData.Stride * overlayBitmap.Height];

            int pixelSize = overlayData.Stride / overlayBitmap.Width;

            // get a pointer to the to first line (=first pixel)
            IntPtr ptr = data.Scan0;
            IntPtr overlayPtr = overlayData.Scan0;

            // create a byte copy of the heightmap data
            System.Runtime.InteropServices.Marshal.Copy(overlayPtr, overlayCopy, 0, overlayData.Stride * overlayBitmap.Height);

            // create the color data

            // standard format overlay (positive values only)
            if (overlayBitmap.Width == 256)
            {
                for (int y = 0; y < heights.Height; y++)
                {
                    for (int x = 0; x < heights.Width; x++)
                    {
                        int index = y * data.Stride + x * pixelSize;

                        int current = (heights[x + y * heights.Width] / 128);

                        if (current < 0) current = 0;

                        // prevent water bleeding onto the coastline
                        if (heights[x + y * heights.Width] > 0 && current == 0) current = 1;

                        for (int channelIndex = 0; channelIndex < pixelSize; channelIndex++)
                        {
                            bytes[index + channelIndex] = overlayCopy[current * pixelSize + channelIndex];
                        }
                    }
                }
            }
            // extended overlay (positive AND negative values)
            else
            {
                for (int y = 0; y < heights.Height; y++)
                {
                    for(int x = 0; x < heights.Width; x++)
                    {
                        int index = y * data.Stride + x * pixelSize;

                        int current = 255 + (heights[x + y * heights.Width] / 128);

                        if (current < 0 || current > 511)
                        {
                            throw new Exception("This cannot happen");
                        }

                        // prevent water bleeding onto the coastline
                        if (current == 255 && heights[x + y * heights.Width] > 0) current = 256;
                     
                        for (int channelIndex = 0; channelIndex < pixelSize; channelIndex++)
                        {
                            bytes[index + channelIndex] = overlayCopy[current * pixelSize + channelIndex];
                        }
                    }
                }
            }

            // copy the data into the bitmap
            System.Runtime.InteropServices.Marshal.Copy(bytes, 0, ptr, data.Stride * bitmap.Height);

            // unlock the bits
            bitmap.UnlockBits(data);

            return bitmap;
        }
コード例 #41
0
ファイル: ViewportManager.cs プロジェクト: hamstah/geogen
        public void SetTerrain(HeightData original){
            Config config = this.GetConfig();

            try
            {
                // store original's size
                int originalHeight = original.Height;
                int originalWidth = original.Width;
                // load the overlay pattern
                //System.Drawing.Bitmap overlayBitmap = new System.Drawing.Bitmap("../overlays/Topographic.bmp");

                // prepare memory space for the newly created color data
                this.heightData = Main.GetResizedHeightData(original, Math.Min(original.Width, (int)config.ModelDetailLevel), Math.Min(original.Height, (int)config.ModelDetailLevel));

                this.textureBase = Main.GetResizedHeightData(original, Math.Min(original.Width, (int)config.TextureDetailLevel), Math.Min(original.Height, (int)config.TextureDetailLevel));

                // release some memory (to prevent OutOfMemory exception)
              // original = null;

                // dimension multipliers
                float fWidth = 100f / (float)this.heightData.Width;
                float fHeight = 100f / (float)this.heightData.Height;
                float texFWidth = fWidth;
                float texFHeight = fHeight;
                float offsetX = 0;
                float offsetY = 0;

                // adjust the multipliers for non-square bitmaps
                if (originalHeight > originalWidth)
                {
                    offsetY = (float)((float)(this.heightData.Height - this.heightData.Width) * 100f / (float)this.heightData.Height) / 2f;
                    fWidth *= (float)originalWidth / (float)originalHeight;
                }
                else if (originalHeight < originalWidth)
                {
                    offsetY = (float)((float)(this.heightData.Width - this.heightData.Height) * 100f / (float)this.heightData.Width) / 2f;
                    fHeight *= (float)originalHeight / (float)originalWidth;
                }

                   
                // the vertex array for the model
                Vertex[] vertices = new Vertex[this.heightData.Length ];

                // fill in vertex data (only position and texcoords for now)
                for (int y = 0; y < this.heightData.Height; y++)
                {
                    float fy = (float)y;

                    // precalculate some stuff that stays constant for whole row
                    float yPos = offsetY + (fy + 0.5f) * fHeight;
                    float texYPos = (fy + 0.5f) * texFHeight;

                    for (int x = 0; x < this.heightData.Width; x++)
                    {
                        float fx = (float)x;

                        int vertexIndex = x + y * this.heightData.Width;

                        vertices[vertexIndex].Position.X = offsetX + fx * fWidth;
                        vertices[vertexIndex].Position.Y = yPos;
                        vertices[vertexIndex].Position.Z = (float)((float)this.heightData[x, y] * 0.005f / 128f);

                        if (!this.config.enableTerrainUnderZero && vertices[vertexIndex].Position.Z < 0) vertices[vertexIndex].Position.Z = 0;

                        vertices[vertexIndex].TexCoord.X = (fx + 0.5f) * texFWidth / 100f;
                        vertices[vertexIndex].TexCoord.Y = texYPos / 100f;
                    }
                }

                uint[] indices = new uint[this.heightData.Length * 6];

                // build index array
                for (int y = 0; y < this.heightData.Height - 1; y++)
                {
                    for (int x = 0; x < this.heightData.Width - 1; x++)
                    {
                        float fx = (float)x;

                        int vertexIndex = (x + y * this.heightData.Width) * 6;

                        // first triangle
                        indices[vertexIndex] = (uint)(x + y * this.heightData.Width);
                        indices[vertexIndex + 1] = (uint)(x + 1 + y * this.heightData.Width);
                        indices[vertexIndex + 2] = (uint)(x + (y + 1) * this.heightData.Width);

                        // second triangle                        
                        indices[vertexIndex + 3] = (uint)(x + 1 + (y + 1) * this.heightData.Width);
                        indices[vertexIndex + 4] = (uint)(x + (y + 1) * this.heightData.Width);
                        indices[vertexIndex + 5] = (uint)(x + 1 + y * this.heightData.Width);
                    }
                }

                // build face normals
                Vector3[] faceNormals = new Vector3[(this.heightData.Width - 1) * (this.heightData.Height - 1) * 2];

                for (int y = 0; y < this.heightData.Height - 1; y++)
                {
                    for (int x = 0; x < this.heightData.Width - 1; x++)
                    {
                        faceNormals[(x + y * (this.heightData.Width - 1)) * 2] = this.CalculateNormal(vertices[x + (y + 1) * this.heightData.Width].Position, vertices[x + y * this.heightData.Width].Position, vertices[(x + 1) + y * this.heightData.Width].Position);
                        faceNormals[(x + y * (this.heightData.Width - 1)) * 2 + 1] = this.CalculateNormal(vertices[x + (y + 1) * this.heightData.Width].Position, vertices[x + y * this.heightData.Width].Position, vertices[(x + 1) + (y + 1) * this.heightData.Width].Position);
                    }
                }

                // build vertex normals
                for (int y = 0; y < this.heightData.Height; y++)
                {
                    for (int x = 0; x < this.heightData.Width; x++)
                    {
                        int faceCount = 0;

                        // upper left triangle
                        if (x > 0 && y > 0)
                        {
                            vertices[x + y * this.heightData.Width].Normal = faceNormals[((x - 1) + (y - 1) * (this.heightData.Width - 1)) * 2 + 1] ;

                            faceCount++;
                        }

                        // bottom left triangles
                        if (x > 0 && y < this.heightData.Height - 1)
                        {
                            vertices[x + y * this.heightData.Width].Normal += faceNormals[((x - 1) + y * (this.heightData.Width - 1)) * 2];
                            vertices[x + y * this.heightData.Width].Normal += faceNormals[((x - 1) + y * (this.heightData.Width - 1)) * 2 + 1];

                            faceCount += 2;
                        }

                        // upper right triangles
                        if (x < this.heightData.Width - 1 && y > 0)
                        {
                            vertices[x + y * this.heightData.Width].Normal += faceNormals[(x + (y - 1) * (this.heightData.Width - 1)) * 2];
                            vertices[x + y * this.heightData.Width].Normal += faceNormals[(x + (y - 1) * (this.heightData.Width - 1)) * 2 + 1];

                            faceCount += 2;
                        }

                        if (x < this.heightData.Width - 1 && y < this.heightData.Height - 1)
                        {
                            vertices[x + y * this.heightData.Width].Normal += faceNormals[(x + y * (this.heightData.Width - 1)) * 2];

                            faceCount++;
                        }

                        vertices[x + y * this.heightData.Width].Normal /= faceCount;
                    }
                }

                // release the context from the GUI thread
                this.Invoke(new System.Windows.Forms.MethodInvoker(delegate()
                {
                    viewport.Context.MakeCurrent(null);
                }));

                // grab the context for this thread
                viewport.MakeCurrent();

                // delete the previous buffer content
                if (this.vertexBufferHandle != 0)
                {
                    GL.DeleteBuffers(1, ref this.vertexBufferHandle);
                }

                // allocate the buffer
                GL.GenBuffers(1, out this.vertexBufferHandle);
                GL.GenBuffers(1, out this.indexBufferHandle);

                // tell that we are using that buffer
                GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);

                GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * 8 * sizeof(float)), vertices, BufferUsageHint.StaticDraw);
                
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, this.indexBufferHandle);

                // upload the data into the buffer into GPU
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(uint)), indices, BufferUsageHint.StaticDraw);


                // make sure the massive vertex array is gone from RAM
                vertices = null;
                indices = null;

                // release the context from current thread
                viewport.Context.MakeCurrent(null);

                try
                {
                    this.Invoke(new System.Windows.Forms.MethodInvoker(delegate()
                    {
                        try
                        {
                            // regrab the context for the GUI thread
                            viewport.MakeCurrent();

                            // rebuild the texture
                            this.ApplyTexture();

                            // UI stuff
                            this.Output3dButtonsOn();
                            this.viewport.Invalidate();

                            this.HideBuildingModel();
                        }
                        catch (Exception e)
                        {

                        }
                    }));
                }
                // this might throw exceptions in case the main thread was terminated while this thread is running
                catch (Exception e) { 
                
                };
            }
            catch (OutOfMemoryException)
            {
                try{
                    this.Invoke(new System.Windows.Forms.MethodInvoker(delegate()
                    {
                        this.HideBuildingModel();

                        this.OutOfMemory();
                    }));
                }
                catch{
                    return;
                };
            }
        }