Exemplo n.º 1
0
    internal void Spawn()
    {
        Debug.Log("spawning");
        Polygon start = FindObjectOfType <SetPlayerSpawnPos>().SpawningPoly;
        var     path  = new List <Node <Polygon> >();
        var     exit  = Instantiate(_exitPrefab);

start:
        VoronoiGenerator.DrawNodeGraphLine(start.Node, _angle, ref path);

        var exitSite = path.Last();

        //var exitSite = path[(int)(path.Count * 0.8f)];
        if (!exitSite.Data.IsWall && exitSite.ConnectionAngles.Any((i) => i.Value.Data.IsWall))
        {
            exitSite = exitSite.ConnectionAngles.First((i) => i.Value.Data.IsWall).Value;
        }

        if (!exitSite.Data.IsWall && _angle < 180f)
        {
            //_angle += 10f;
            //goto start;
        }
        ;
        var pos = exitSite.Data.Centre;

        exit.transform.position = new Vector3(pos.x, pos.y, -7);
        _spawned = false;
        _path    = path;
    }
Exemplo n.º 2
0
 void Start()
 {
     _voronoiGen = _levelGenerator.GetComponent <VoronoiGenerator>();
     _voronoiGen.Generate();
     _voronoiGen.ScaleAllPolies(Scale);
     OnGenerationComplete?.Invoke();
 }
Exemplo n.º 3
0
        /// <summary>
        /// Generate a Voronoi Diagram from the generated points
        /// </summary>
        private void GenerateVoronoi()
        {
            //check if there are enough points
            if (_points == null || _points.Count <= 2 || _voronoiDiagram.Triangulation == null)
            {
                Console.WriteLine("No points available!");
                GeneratePoints(PointsToGenerate);
                //return;
            }

            _baseColor = Extensions.Extensions.RandomColor();

            _voronoiSettings.VoronoiAlgorithm = VoronoiAlgorithm;

            //create voronoi using specified algorithm
            var timer = Stopwatch.StartNew();

            _voronoiDiagram = VoronoiGenerator.CreateVoronoi(_points, _voronoiSettings);
            timer.Stop();

            if (_voronoiDiagram == null)
            {
                return;
            }

            //update info
            var time = timer.ElapsedMilliseconds / 1000.0;

            GenerationTimeText = $"For {_points.Count} points using {VoronoiAlgorithm.ToString()}: {time} seconds.";

            //Update canvas
            RefreshCanvas();
        }
Exemplo n.º 4
0
        public SimpleVoronoi(IValueGenerator <float> random, VoronoiGenerator parameters, List <ShapeRelaxManipulator> manipulatorses)
        {
            _prng = random;
            _prng.Init();
            _manipulators = manipulatorses;

            _parameters = parameters;
        }
Exemplo n.º 5
0
    public void Generate()
    {
        if (!_generatedVertexOrder)
        {
            GenerateVertexOrder();
        }
        _generator = GetComponent <VoronoiGenerator>();

        if (_generator == null || _generator.Polygons.Count == 0)
        {
            return;
        }
        // 3 is the least amount of sides for a polygon
        var polies = _generator.Polygons.Where((p) => p.Vertices.Count >= 3).ToList();

        var          corner0 = (polies.First().Centre);
        var          corner1 = (polies.Last().Centre);
        List <Bound> bounds  = new List <Bound>()
        {
            //	new Bound(corner0 - new Vector2(2f, 2f), corner1 + new Vector2(2, 2))
            new Bound(corner0 - new Vector2(0.2f, 0.2f), corner1 + new Vector2(0.2f, 0.2f))
        };
        int power = Mathf.CeilToInt(Mathf.Log(polies.Count / _chunkSize, 4f));

        if (polies.Count < _chunkSize)
        {
            power = 0;
        }

        for (int i = 0; i < power; i++)
        {
            // this is the snapshot the count
            int boundCount = bounds.Count;
            var newBounds  = new List <Bound>();
            //for (int bound = 0; bound < boundCount; bound++)
            for (int bound = boundCount - 1; bound >= 0; bound--)
            {
                newBounds.AddRange(bounds[bound].Subdivide());
                bounds.RemoveAt(bound);
            }
            bounds.AddRange(newBounds);
        }
        foreach (var bound in bounds)
        {
            List <Polygon> poliesInChunk = new List <Polygon>();

            for (int poly = polies.Count - 1; poly >= 0; poly--)
            {
                if (bound.Contains(polies[poly].Centre))
                {
                    poliesInChunk.Add(polies[poly]);
                    polies.RemoveAt(poly);
                }
            }
            var go = GenerateMesh(poliesInChunk);
            go.transform.SetParent(transform);
        }
    }
Exemplo n.º 6
0
        public override ISubGenerator Build(int seed)
        {
            var np = _noiseBuilder.Random(new Rand(seed)).Build();
            var lp = _layerBuilder.Build();
            // TODO change rand approach
            var rnd2 = new RandomSeeded(seed);
            var sd   = new SegmentDivider(rnd2, 30, 1);
            var c    = new VoronoiConverter(sd);
            var g    = new VoronoiGenerator(c);
            var gg   = new VoronoiAreaGenerator(g, new Rand(seed));

            // todo Use parameters
            return(new MountainGenerator(new VisualLogger(), gg, np, lp)
            {
                Influence = _influence
            });
        }
Exemplo n.º 7
0
    private void Spawn()
    {
        _voronoi = FindObjectOfType <VoronoiGenerator>();
        // get a random poly as a starting point
        int     randIndex;
        Polygon poly;

        do
        {
            //randIndex = Random.Range(0, _voronoi.Polygons.Count);
            randIndex = _levelSeeds[Random.Range(0, _levelSeeds.Length)];

            poly = _voronoi.Polygons[randIndex];
            // keep picking random polies till we find a valid spawn position
        } while (!IsValidSpawn(poly));
        Debug.Log(randIndex);
        SpawningPoly       = poly;
        transform.position = new Vector3(poly.Centre.x, poly.Centre.y, transform.position.z);
        _spawned           = false;
    }
Exemplo n.º 8
0
    private List <Vector2> GetPoints()
    {
        List <Vector2> points = null;

        if (pointGeneration == PointGeneration.Random)
        {
            points = VoronoiGenerator.GetVector2Points(seed, (meshSize / pointSpacing) * (meshSize / pointSpacing), meshSize);
        }
        else if (pointGeneration == PointGeneration.PoissonDisc)
        {
            var poisson = new PoissonDiscSampler(meshSize, meshSize, pointSpacing, seed);
            points = poisson.Samples().ToList();
        }
        else if (pointGeneration == PointGeneration.Grid)
        {
            points = new List <Vector2>();
            for (int x = pointSpacing; x < meshSize; x += pointSpacing)
            {
                for (int y = pointSpacing; y < meshSize; y += pointSpacing)
                {
                    points.Add(new Vector2(x, y));
                }
            }
        }
        else if (pointGeneration == PointGeneration.OffsetGrid)
        {
            points = new List <Vector2>();
            for (int x = pointSpacing; x < meshSize; x += pointSpacing)
            {
                bool even = false;
                for (int y = pointSpacing; y < meshSize; y += pointSpacing)
                {
                    var newX = even ? x : x - (pointSpacing / 2f);
                    points.Add(new Vector2(newX, y));
                    even = !even;
                }
            }
        }

        return(points);
    }
Exemplo n.º 9
0
        private static ILayer printMountainProfile(int countOfCells, ISegmendDivider sd)
        {
            var l = new Layer2DObject(res);

            // TODO change rand approach

            var rnd = new Rand(seed);


            var c  = new VoronoiConverter(sd);
            var g  = new VoronoiGenerator(c);
            var gg = new VoronoiAreaGenerator(g, rnd);

            var vd = new VoronoiAreaDrawer();


            var areas = gg.GenerateAreas(res, res, countOfCells);

            vd.PrintToLayer(l, areas, Vector2.Zero);
            return(l);
        }
Exemplo n.º 10
0
        private void GenerateCity()
        {
            //seed random
            if (!GenerationSettings.UseSeed)
            {
                GenerationSettings.Seed = DateTime.Now.GetHashCode();
            }
            //Store Settings
            var width  = GenerationSettings.Width;
            var length = GenerationSettings.Length;

            //Parent.transform.position = citypos;
            GenerationSettings.StartX = Parent.transform.position.x - width / 2.0;
            GenerationSettings.StartY = Parent.transform.position.z - length / 2.0;

            //Generate Points and diagram
            var points = PointGenerator.Generate(GenerationSettings);

            VoronoiDiagram = VoronoiGenerator.CreateVoronoi(points, GenerationSettings);

            //generate city districts and roads
            _cityData = CityBuilder.GenerateCity(CitySettings, VoronoiDiagram);
        }
Exemplo n.º 11
0
    public List <GameObject> Explode(Vector3 impact, Vector3 direction, GameObject original)
    {
        List <VoronoiGenerator.VoronoiCell> cells = VoronoiGenerator.GenerateVoronoiSet(VoronoiGenerator.RandomPointSet(original.GetComponent <MeshFilter>().sharedMesh.bounds, 200));
        List <GameObject> parts = new List <GameObject>();

        foreach (VoronoiGenerator.VoronoiCell voronoiCell in cells)
        {
            GameObject cell;
            if (cell = MeshSlicerUtility.CellSlice(original, voronoiCell.faces, false))
            {
                MeshCollider meshCollider = cell.AddComponent <MeshCollider>();
                meshCollider.convex     = true;
                meshCollider.sharedMesh = cell.GetComponent <MeshFilter>().sharedMesh;

                Rigidbody rigidbody = cell.AddComponent <Rigidbody>();
                rigidbody.collisionDetectionMode = CollisionDetectionMode.Continuous;

                parts.Add(cell);
            }
        }

        return(parts);
    }
Exemplo n.º 12
0
        private static void printVoronoi(int countOfCells, ISegmendDivider sd)
        {
            var l = new Layer2DObject(res);

            // TODO change rand approach

            var rnd = new Rand(seed);


            var c  = new VoronoiConverter(sd);
            var g  = new VoronoiGenerator(c);
            var gg = new VoronoiAreaGenerator(g, rnd);

            var vd = new VoronoiAreaDrawer();

            var areas = gg.GenerateAreas(res, res * .5f, countOfCells);



            vd.PrintToLayer(l, areas, new Vector2());
            var vl = new VisualLogger();

            vl.Log(l, "profile");
        }
Exemplo n.º 13
0
 public void GeneratePoints()
 {
     _points = VoronoiGenerator.RandomPointSet(_meshFilter.sharedMesh.bounds, 10);
 }
Exemplo n.º 14
0
        private void _generateTerrain()
        {
            try
            {
                IGenerator generator = null;

                switch (_configurationManager.Algorithm)
                {
                case GeneratorAlgorithm.PerlinNoise:
                    generator = new PerlinNoiseGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.Hill:
                    generator = new HillAlgorithmGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.Random:
                    generator = new RandomGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.Rectangle:
                    generator = new RectangleGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.Voronoi:
                    generator = new VoronoiGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.SimplexNoise:
                    generator = new SimplexNoise(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.DiamondSquare:
                    generator = new DiamondSquareGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.RandomWalk:
                    generator = new RandomWalkGenerator(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                case GeneratorAlgorithm.DrunkardWalk:
                    generator = new DrunkardWalk(GraphicsDevice, Graphics, _configurationManager.Parameters);
                    break;

                default:
                    throw new NotImplementedException("Unknown algorithm");
                }
                if (generator == null)
                {
                    throw new NullReferenceException("Generator cannot be null");
                }

                var timeStart = System.DateTime.Now;
                Scene.AddObjectToRender(generator.Generate());
                Logger.Log.Info("Generated time = " + (DateTime.Now - timeStart).TotalMilliseconds + " ms for " + _configurationManager.Algorithm.ToString());
            }
            catch (Exception e)
            {
                Logger.Log.Error(e);
                throw;
            }
        }
Exemplo n.º 15
0
        void OnSceneGUI()
        {
            VoronoiGenerator gen = (VoronoiGenerator)target;

            if (gen.lr != null)
            {
                if (quad == null || gen.wasReset)
                {
                    if (VoronoiGenerator.instance == null)
                    {
                        gen.GenerateNoisyLineDebug();
                    }
                    var lr = gen.lr;
                    VoronoiGenerator.TryGetLineIntersections(
                        gen.startControl, gen.endControl, gen.startNoisy, gen.endNoisy,
                        out Vector2 intersectPoint, out float t1, out float t2);
                    Debug.Log("t1: " + t1 + " t2: " + t2);

                    quad = new Quad(gen.startControl, gen.endControl, gen.startNoisy, gen.endNoisy,
                                    gen.debugSubdivisions, -t1, gen.debugAmplitude, new System.Random());
                    List <Vector3> positions = new List <Vector3>();
                    positions.Add(gen.startNoisy);
                    positions.AddRange(quad.points);
                    positions.Add(gen.endNoisy);
                    lr.SetPositions(positions.ToArray());

                    gen.wasReset = false;
                }
                else
                {
                    quad.Draw();
                }
            }

            if (gen.dGraph != null && gen.viewDelaunayTriangles)
            {
                Handles.color = Color.red;
                foreach (var edge in gen.dGraph.edges)
                {
                    Handles.DrawDottedLine(edge.start.position, edge.end.position, 2);
                }
            }

            if (gen.vGraph != null && gen.viewVoronoiPolygons)
            {
                if (gen.viewIntersectionDirections)
                {
                    if (VoronoiGraph.boundCrossingEdges != null)
                    {
                        foreach (MapSide mapSide in (MapSide[])Enum.GetValues(typeof(MapSide)))
                        {
                            if (mapSide == MapSide.Inside)
                            {
                                continue;
                            }
                            Handles.color = new Color(1, .62f, .016f, 1);
                            for (int i = 0; i < VoronoiGraph.boundCrossingEdges[mapSide].Count; ++i)
                            {
                                var     edge = VoronoiGraph.boundCrossingEdges[mapSide][i];
                                Vector2 nextPos;
                                if (i == VoronoiGraph.boundCrossingEdges[mapSide].Count - 1)
                                {
                                    //nextPos = borderEndPoints[mapSide].Item2;
                                    continue;
                                }
                                else
                                {
                                    nextPos = VoronoiGraph.boundCrossingEdges[mapSide][i + 1].intersectPosition;
                                }
                                Handles.ArrowHandleCap(i, edge.intersectPosition,
                                                       Quaternion.LookRotation(Vector3.right + new Vector3(0, .5f, 0)),
                                                       Vector2.Distance(edge.intersectPosition, nextPos), EventType.Repaint);
                                Handles.Label((edge.intersectPosition + nextPos) / 2, "" + i);
                            }
                        }
                    }
                }

                style.normal.textColor = Color.black;
                if (gen.viewCorners)
                {
                    foreach (var corner in VoronoiGraph.uniqueCorners)
                    {
                        if (corner.isInvalidated)
                        {
                            Handles.color = new Color(.5f, .5f, .5f, .5f);
                        }
                        else if (corner.isOOB)
                        {
                            Handles.color = Color.red;
                        }
                        else if (corner.isOnBorder)
                        {
                            Handles.color = cornerGreen;
                        }
                        else
                        {
                            Handles.color = Color.white;
                        }

                        Handles.SphereHandleCap(0, corner.position, Quaternion.identity, .25f, EventType.Repaint);
                        if (gen.viewCornerIDs)
                        {
                            Handles.Label(corner.position + textOffset, "" + corner.num, style);
                        }
                    }
                }

                int intersectCount = 0;
                style.normal.textColor = Color.yellow;
                foreach (var edge in VoronoiGraph.uniqueVEdges)
                {
                    if (edge.start.isOnBorder && edge.end.isOnBorder)
                    {
                        Handles.color = Color.green;
                    }
                    else if (!edge.start.isOOB && !edge.end.isOOB)
                    {
                        Handles.color = Color.blue;
                    }
                    else if ((edge.start.isOOB ^ edge.end.isOOB) && !edge.start.isOnBorder && !edge.end.isOnBorder)
                    {
                        Handles.color          = Color.yellow;
                        style.normal.textColor = Color.yellow;
                        if (gen.viewIntersections)
                        {
                            foreach (var intersection in VoronoiGenerator.FindMapBoundsIntersection(edge.start.position, edge.end.position))
                            {
                                Handles.CylinderHandleCap(0, intersection, Quaternion.identity, .4f, EventType.Repaint);
                                if (gen.viewIntersectionIDs)
                                {
                                    Handles.Label(intersection + textOffset, "" + (intersectCount++), style);
                                }
                            }
                        }
                    }
                    else
                    {
                        Handles.color = Color.red;
                        if (gen.viewIntersections)
                        {
                            foreach (var intersection in VoronoiGenerator.FindMapBoundsIntersection(edge.start.position, edge.end.position))
                            {                             // this is a very rare occurence of an edge that starts on a border and intersects with a different map edge.
                                Handles.CylinderHandleCap(0, intersection, Quaternion.identity, .4f, EventType.Repaint);
                                if (gen.viewIntersectionIDs)
                                {
                                    Handles.Label(intersection + textOffset, "" + (intersectCount++), style);
                                }
                                Handles.color = Color.yellow;
                            }
                        }
                    }

                    Handles.DrawDottedLine(edge.start.position, edge.end.position, 2);
                    if (gen.viewEdgeIDs)
                    {
                        style.normal.textColor = Color.cyan;
                        Handles.Label((edge.start.position + edge.end.position) * .5f + textOffset, "" + edge.id, style);
                    }
                }



                Handles.color = Color.cyan;
                foreach (var polygon in VoronoiGenerator.debugPolygons)
                {
                    foreach (var edge in polygon.GetVoronoiEdges())
                    {
                        Handles.DrawDottedLine(edge.start.position, edge.end.position, 1);
                    }

                    foreach (var corner in polygon.corners)
                    {
                        Handles.SphereHandleCap(0, corner.position, Quaternion.identity, .175f, EventType.Repaint);
                    }

                    int i = 0;
                    style.normal.textColor = Color.cyan;
                    foreach (var edge in polygon.GetVoronoiEdges())
                    {
                        Handles.Label((edge.start.position + edge.end.position) / 2, "" + i, style);
                        ++i;
                    }

                    style.normal.textColor = Color.white;
                    i = 0;
                    foreach (var corner in polygon.corners)
                    {
                        Handles.Label(corner.position + textOffset, "" + i, style);
                        ++i;
                    }
                }

                Handles.color = Color.magenta;
                foreach (var edge in VoronoiGenerator.debugEdges)
                {
                    Handles.DrawDottedLine(edge.start.position, edge.end.position, 1);
                }

                foreach (var corner in VoronoiGenerator.debugCorners)
                {
                    Handles.SphereHandleCap(0, corner.position, Quaternion.identity, .175f, EventType.Repaint);
                }
            }

            if (gen.regions != null && gen.viewRegionIDs)
            {
                foreach (var region in gen.regions)
                {
                    if (region == null || region.polygon == null)
                    {
                        break;
                    }
                    Handles.Label(region.polygon.centroid.position, "" + region.id, style);
                }
            }

            if (VoronoiGraph.uniqueCorners != null && gen.debugSlopeDirections)
            {
                foreach (Corner corner in VoronoiGraph.uniqueCorners)
                {
                    if (corner.downSlope != null)
                    {
                        Vector3 cornerPos = Quaternion.AngleAxis(90, Vector3.right) * corner.position;
                        Vector3 targetPos = Quaternion.AngleAxis(90, Vector3.right) * corner.downSlope.position;

                        Handles.ArrowHandleCap(0, cornerPos,
                                               Quaternion.LookRotation(targetPos - cornerPos, Vector3.up), 1, EventType.Repaint);
                    }
                }
            }
        }
Exemplo n.º 16
0
        public override void OnInspectorGUI()
        {
            VoronoiGenerator gen = (VoronoiGenerator)target;

            using (var check = new EditorGUI.ChangeCheckScope())
            {
                mapGenerationSettingsFoldout = EditorGUILayout.Foldout(mapGenerationSettingsFoldout, new GUIContent("Map Generation Settings"));
                if (mapGenerationSettingsFoldout)
                {
                    EditorGUI.indentLevel = 1;
                    gen.newRandomSeed     = EditorGUILayout.Toggle(new GUIContent("New RandomSeed"), gen.newRandomSeed);
                    gen.randomSeed        = EditorGUILayout.DelayedTextField(new GUIContent("RandomSeed"), gen.randomSeed);
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("mapWidth"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("mapHeight"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("regionAmount"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("minSqrDistBtwnSites"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("minDistBtwnSiteAndBorder"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("minDistBtwnCornerAndBorder"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("minEdgeLengthToMerge"));
                    GUI.enabled = false;
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("mergeNearCorners"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("clampToMapBounds"));
                    GUI.enabled           = true;
                    EditorGUI.indentLevel = 0;
                }

                gen.borderSettingsFoldout = EditorGUILayout.Foldout(gen.borderSettingsFoldout, new GUIContent("Border Settings"));
                if (gen.borderSettingsFoldout)
                {
                    EditorGUI.indentLevel = 1;
                    bool borders = EditorGUILayout.Toggle(new GUIContent("Show Borders"), gen.bordersEnabled);
                    if (borders != gen.bordersEnabled)
                    {
                        gen.ToggleBorders(borders);
                    }
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("subdivisions"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("amplitude"));
                    EditorGUI.indentLevel = 0;
                }

                EditorGUILayout.PropertyField(serializedObject.FindProperty("regionMaterial"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("sideMaterial"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("regionPrefab"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("regionHolder"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("noisePreviewMeshRenderer"));

                if (check.changed || GUILayout.Button("Generate Voronoi"))
                {
                    AtomosZ.EditorTools.EditorUtils.ClearLogConsole();
                    gen.GenerateMap();
                    EditorUtility.SetDirty(target);
                }

                if (GUILayout.Button("Clear Map"))
                {
                    gen.ClearMap();
                }
            }

            using (var check = new EditorGUI.ChangeCheckScope())
            {
                EditorGUILayout.PropertyField(serializedObject.FindProperty("noiseSettings"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("heightMapSettings"));
                if (check.changed)
                {
                    gen.GenerateTexture();
                }
            }

            gen.mapDebugFoldout = EditorGUILayout.Foldout(gen.mapDebugFoldout, new GUIContent("Map Debug Settings"));
            if (gen.mapDebugFoldout)
            {
                EditorGUI.indentLevel = 1;
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewDelaunayCircles"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewDelaunayTriangles"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewCenteroids"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewVoronoiPolygons"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewCorners"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewCornerIDs"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewEdgeIDs"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewIntersections"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewIntersectionIDs"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewIntersectionDirections"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("viewRegionIDs"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("debugSlopeDirections"));
                gen.debugBorders = EditorGUILayout.Toggle(new GUIContent("Debug Borders"), gen.debugBorders);
                if (gen.debugBorders)
                {
                    EditorGUI.indentLevel = 2;
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("topBorder"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("rightBorder"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("bottomBorder"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("leftBorder"));
                    EditorGUI.indentLevel = 1;
                }

                gen.debugNoisyLine = EditorGUILayout.Foldout(gen.debugNoisyLine, new GUIContent("Noisy Line Debug"));
                if (gen.debugNoisyLine)
                {
                    EditorGUI.indentLevel = 2;

                    EditorGUILayout.PropertyField(serializedObject.FindProperty("debugSubdivisions"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("debugAmplitude"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("startNoisy"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("endNoisy"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("startControl"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("endControl"));

                    if (GUILayout.Button("Generate Noisy Line"))
                    {
                        AtomosZ.EditorTools.EditorUtils.ClearLogConsole();
                        gen.GenerateNoisyLineDebug();
                        EditorUtility.SetDirty(target);
                    }
                    EditorGUI.indentLevel = 1;
                }

                EditorGUI.indentLevel = 0;
            }

            serializedObject.ApplyModifiedProperties();
        }