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)); }