Esempio n. 1
0
        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();
                }
            }
        }
Esempio n. 2
0
        public void ReturnHandler(object sender, MapReturnedEventArgs e)
        {
            Config config = Main.Get().GetConfig();

            HeightData data = Main.GetResizedHeightData(e.HeightMap, Math.Min(e.HeightMap.Width, (int)config.mapDetailLevel), Math.Min(e.HeightMap.Height, (int)config.mapDetailLevel));

            e.HeightMap.Dispose();

            Main.StretchHeightValues(ref data);

            if (this.maps.Contains(e.Label))
            {
                this.WriteToConsole("Warning: Map with label \"" + e.Label + "\" was returned more than once!");
                this.maps[e.Label] = data;
            }
            else
            {
                this.maps.Add(e.Label, data);
            }
        }
Esempio n. 3
0
        public void ExecuteScript(string script, bool syntaxCheckOnly, uint[] parameters)
        {
            // kill current syntax check in progress (if any is running)
            if (this.IsGGenRunning() && mode == Mode.SyntaxCheck && syntaxCheckOnly == false)
            {
                // wait for the syntax check to finish (it usually takes just milliseconds)
                this.GGenThread.Join();

                // do the check one the requested script is finished
                this.ScheduleSyntaxCheck();
            }
            // syntax checks are not allowed while a script is being executed
            else if (this.IsGGenRunning() && syntaxCheckOnly == true)
            {
                // do the check one the requested script is finished
                if (!this.isCheckScheduled)
                {
                    this.ScheduleSyntaxCheck();
                }

                return;
            }
            // having two generators running at once shouldn't happen
            else if (this.IsGGenRunning() && mode == Mode.Standard)
            {
                throw new Exception("Two GeoGens can't possibly be running at one time");
            }

            if (!syntaxCheckOnly)
            {
                this.mode = Mode.Standard;
                this.ButtonsRunMode();
                this.AddStatus("Executing");

                this.ClearData();

                this.WriteToConsole("Starting at " + DateTime.Now.ToString("HH:mm:ss") + "...");
            }
            else
            {
                this.mode = Mode.SyntaxCheck;

                this.lastCheckContent = "";
                this.AddStatus("Checking syntax");
            }

            System.Threading.ThreadStart starter = new System.Threading.ThreadStart(delegate
            {
                try
                {
                    try
                    {
                        ggen.SetScript(script);
                    }
                    catch (SyntaxErrorException)
                    {
                        this.MapGenerationFailed("Compilation failed!");

                        return;
                    }

                    try
                    {
                        ggen.LoadArgs();
                    }
                    catch (ArgsUnreadableException)
                    {
                        this.MapGenerationFailed("Map header is unreadable!");

                        return;
                    }

                    // do not generate the map during syntax check runs
                    if (!syntaxCheckOnly)
                    {
                        // no list of arguments was passed to the function -> use params from the param table
                        if (parameters == null)
                        {
                            var zipped = this.parameters.Item.Cast <PropertyGridEx.CustomProperty>().Zip(ggen.Args, (Property, Arg) => new { Property, Arg });

                            foreach (var item in zipped)
                            {
                                // fill in only matching arguments
                                if (item.Property.Type.Name == "Boolean" && item.Arg.Type == ScriptArgType.Bool)
                                {
                                    item.Arg.Value = (uint)item.Property.Value;
                                }

                                else if (item.Property.Type.Name == "UInt32" && item.Arg.Type == ScriptArgType.Int)
                                {
                                    item.Arg.Value = (uint)item.Property.Value;
                                }
                                else if (item.Property.Type.Name == "Int32" && item.Arg.Type == ScriptArgType.Int)
                                {
                                    item.Arg.Value = (uint)((int)item.Property.Value);
                                }
                                else if (item.Property.Type.Name == "String" && item.Arg.Type == ScriptArgType.Enum)
                                {
                                    item.Arg.Value = (uint)item.Property.Choices.IndexOf(item.Property.Value);
                                }
                            }

                            /*int i = 0;
                             * foreach (PropertyGridEx.CustomProperty property in this.parameters.Item)
                             * {
                             *
                             *
                             *  Generator.ScriptArg arg = ggen.Args[i];
                             *
                             *  // we ran out of parameters...
                             *  if (i == ggen.Args.Count())
                             *  {
                             *      break;
                             *  }
                             *
                             *  // fill in only matching arguments
                             *  if (property.Type.Name == "Boolean" && arg.Type == ScriptArgType.Bool)
                             *  {
                             *      arg.Value = (uint)property.Value;
                             *  }
                             *
                             *  else if (property.Type.Name == "UInt32" && arg.Type == ScriptArgType.Int)
                             *  {
                             *      arg.Value = (uint)property.Value;
                             *  }
                             *  else if (property.Type.Name == "Int32" && arg.Type == ScriptArgType.Int)
                             *  {
                             *      arg.Value = (uint)((int)property.Value);
                             *  }
                             *  else if (property.Type.Name == "String" && arg.Type == ScriptArgType.Enum)
                             *  {
                             *      arg.Value = (uint)property.Choices.IndexOf(property.Value);
                             *  }
                             *
                             *  i++;
                             * }*/
                        }
                        // the argument list was passed to the function
                        else
                        {
                            var zipped = parameters.Zip(ggen.Args, (Param, Arg) => new { Param, Arg });

                            foreach (var item in zipped)
                            {
                                item.Arg.Value = item.Param;
                            }

                            /*int i = 0;
                             * foreach (uint currentParam in parameters)
                             * {
                             *  Generator.ScriptArg arg = ggen.Args[i];
                             *
                             *  // we ran out of parameters...
                             *  if (i == ggen.Args.Length)
                             *  {
                             *      break;
                             *  }
                             *
                             *  arg.Value = currentParam;
                             *
                             *  i++;
                             * }*/
                        }

                        this.startTime = System.DateTime.Now.Ticks / 10000;

                        HeightData result;
                        try
                        {
                            if (this.config.seed == 0)
                            {
                                ggen.Seed = (uint)DateTime.Now.Ticks;
                            }
                            else
                            {
                                ggen.Seed = this.config.seed;
                            }

                            result = ggen.Generate();
                        }
                        catch (GenerationFailedException)
                        {
                            this.MapGenerationFailed("Map generation failed!");

                            return;
                        }
                        catch (ExceptionInCallbackException e)
                        {
                            // the thread was aborted
                            if (e.InnerException is ThreadAbortException)
                            {
                                this.ggen.Reset();
                                this.BeginInvoke(new MethodInvoker(delegate()
                                {
                                    this.MapGenerationFailed("Aborted!");
                                }));
                                return;
                            }

                            // else unknown exception, we want to debug this case
                            throw;
                        }

                        // map was generated successfully
                        HeightData result2 = Main.GetResizedHeightData(result, Math.Min(result.Width, (int)config.mapDetailLevel), Math.Min(result.Height, (int)config.mapDetailLevel));

                        result.Dispose();

                        Main.StretchHeightValues(ref result2);

                        maps.Add("[Main]", result2);

                        this.RemoveStatus("Executing");

                        this.Invoke(new MethodInvoker(delegate()
                        {
                            // was this part of a benchmark?
                            if (benchmarkStatus != null)
                            {
                                this.Benchmark();

                                return;
                            }

                            this.ReloadMaps(null);

                            this.WriteToConsole("Finished after " + Math.Round((System.DateTime.Now.Ticks / 10000 - this.startTime) / 1000d, 3) + " seconds!" + Environment.NewLine);

                            this.ButtonsNoRunMode();
                        }));
                    }
                    else
                    {
                        this.Invoke(new MethodInvoker(delegate()
                        {
                            this.RebuildArgsTable();
                            this.SetErrorStatus(false);
                        }));
                    }
                }
                catch (InternalErrorException e)
                {
                    this.WriteToConsole("Error: " + e.InnerException.Message);
                    this.MapGenerationFailed("GeoGen has unexpectedly crashed!");
                }
                finally
                {
                    this.BeginInvoke(new MethodInvoker(delegate()
                    {
                        this.RemoveStatus("Executing");
                        this.RemoveStatus("Checking syntax");
                        this.ExecuteScheduledCheck();
                    }));
                }
            });

            GGenThread = new System.Threading.Thread(starter);

            GGenThread.Start();
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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;
                };
            }
        }