public async void Initialize(uint seed)
 {
     Seed = seed;
     var random = new FastRandom(Seed);
     var settings = await MainEngine.GetEngineInstance().GeneralSettings;
     m_sealevel = settings.SeaLevel;
     m_mountainHeight = settings.MountainHeight - m_sealevel;
     var rescale = settings.BiomeSampleRescale;
     m_detailScale = settings.DetailScale;
     m_sinkHoleDepth = settings.SinkHoleDepth;
     m_biomeThickness = settings.BiomeThickness;
     m_elevation = new SimplexNoise2D(random.NextUInt());
     m_detail = new SimplexNoise2D(random.NextUInt());
     m_detail2 = new SimplexNoise2D(random.NextUInt());
     m_volume = new SimplexNoise3D(random.NextUInt());
     m_voroni = new CellNoise2D(random.NextUInt());
     m_populator = new StructureGenerator(random.NextUInt());
     m_riverGenerator = new PathGenerator(random.NextUInt(), GetHeight);
     m_riverGenerator.InitializePathSystem(0, 0, 256);
     m_biomeGenerator = new BiomeGeneratorCollection(random.NextUInt(), GetHeight, settings.Biomes, rescale, m_sealevel, m_mountainHeight);
     m_provinceGenerator = new ProvinceGeneratorCollection(random.NextUInt(), GetHeight, settings.Provinces, rescale, m_sealevel, m_mountainHeight);
     IsInitialized = true;
 }
 private PathData BuildPathData(SimplexNoise2D noise, int x, int z, int w, Vector2 gradient, GetHeight getHeightFunction, int previousHeight)
 {
     var radius = noise.Perlin(x, z) * 1 + 2;
     return  new PathData(radius, x, z, w, gradient, getHeightFunction, previousHeight);
 }
 private List<PathData> GeneratePath(SimplexNoise2D noise, GetHeight getHeightFunction, PathGraphNode origin, PathGraphNode destination)
 {
     var originProjection = new Vector2(origin.Position.X, origin.Position.Z);
     var destinationProjection = new Vector2(destination.Position.X, destination.Position.Z);
     var gradient = Vector2.Subtract(destinationProjection, originProjection);
     var distance = gradient.LengthSquared();
     gradient.Normalize();
     //just checking if we'll get a NaN so the quality oprtator should be fine
     // ReSharper disable CompareOfFloatsByEqualityOperator
     var deltaX = gradient.X == 0 ? 0 : 1 / Math.Abs(gradient.X);
     var deltaZ = gradient.Y == 0 ? 0 : 1 / Math.Abs(gradient.Y);
     if (deltaX == 0 && deltaZ == 0)
     {
         return new List<PathData>();
     }
     var stepX = Math.Sign(gradient.X);
     var stepZ = Math.Sign(gradient.Y);
     var maxX = 0.0f;
     var maxZ = 0.0f;
     var x = (int)origin.Position.X;
     var z = (int)origin.Position.Z;
     var previousHeight = (int)origin.Position.Y;
     var path = new List<PathData>();
     do
     {
         var node = BuildPathData(noise, x, z, 0, gradient, getHeightFunction, previousHeight);
         path.Add(node);
         previousHeight = (int)node.Position.Y;
         if (deltaZ == 0 || (deltaX != 0 && maxX < maxZ))
         {
             maxX += deltaX;
             x += stepX;
         }
         else
         {
             maxZ += deltaZ;
             z += stepZ;
         }
     } while (Vector2.DistanceSquared(originProjection, new Vector2(x, z)) <= distance);
     // ReSharper restore CompareOfFloatsByEqualityOperator
     return path;
 }
            public PathNodeList(PathGraphNode head, GetHeight getHeightFunction)
            {
                var noise = new SimplexNoise2D(head.Id);
                Head = head;
                var stack = new Stack<PathGraphNode>();
                var minPosX = float.MaxValue;
                var minPosZ = float.MaxValue;
                var maxPosX = -float.MaxValue;
                var maxPosZ = -float.MaxValue;
                m_slices = new Dictionary<PathGraphNode, Dictionary<PathGraphNode, Lazy<List<PathData>>>>();
                stack.Push(head);
                while (stack.Count > 0)
                {
                    var node = stack.Pop();
                    var nodePos = node.Position;

                    if (nodePos.X < minPosX) minPosX = nodePos.X;
                    if (nodePos.Z < minPosZ) minPosZ = nodePos.Z;
                    if (nodePos.X > maxPosX) maxPosX = nodePos.X;
                    if (nodePos.Z > maxPosZ) maxPosZ = nodePos.Z;
                    if (node.Edges.Count(val => val.Value > 0) == 0)
                    {
                        continue;
                    }
                    m_slices[node] = new Dictionary<PathGraphNode, Lazy<List<PathData>>>();
                    foreach (var graphNode in node.Edges)
                    {
                        if (graphNode.Value < 0)
                        {
                            continue;
                        }
                        m_slices[node][graphNode.Key] = new Lazy<List<PathData>>(() => GeneratePath(noise,
                            getHeightFunction, node,
                            graphNode.Key));
                        stack.Push(graphNode.Key);
                    }

                }
                BoundingBox = new BoundingBox(new Vector3(minPosX - 1.5f, 0, minPosZ - 1.5f), new Vector3(maxPosX + 1.5f, 0, maxPosZ + 1.5f));
            }