Example #1
0
 public List<PathData> GetPathLeg(PathGraphNode origin, PathGraphNode destination)
 {
     return m_slices[origin][destination].Value;
 }
Example #2
0
 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;
 }
Example #3
0
            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));
            }
Example #4
0
 private PathData GetRiverData(int x, int z, PathGraphNode nextNode, PathGraphNode lastNode, PathNodeList path)
 {
     var testPoint = new Vector2(x, z);
     var lastNodePos = new Vector2(lastNode.Position.X, lastNode.Position.Z);
     var nextNodePos = new Vector2(nextNode.Position.X, nextNode.Position.Z);
     var distance = MathUtilities.DistanceFromPointToLineSegment(testPoint, lastNodePos, nextNodePos);
     var pathLeg = path.GetPathLeg(lastNode, nextNode);
     var distSquared = Vector2.DistanceSquared(lastNodePos, testPoint) - distance*distance;
     if (distSquared >= 0)
     {
         var dist = Math.Sqrt(distSquared);
         var ratio = dist/Vector2.Distance(lastNodePos, nextNodePos);
         var sliceIndex = (int) (ratio*pathLeg.Count);
         if (sliceIndex < pathLeg.Count)
         {
             var pathSlice = pathLeg[sliceIndex];
             if (distance <= pathSlice.Radius)
             {
                 return pathSlice;
             }
         }
     }
     PathData slice = null;
     foreach (var graphNode in nextNode.Edges)
     {
         if (graphNode.Value <= 0)
         {
             continue;
         }
         var currentSlice = GetRiverData(x, z, graphNode.Key, nextNode, path);
         if (currentSlice != null && (slice == null || currentSlice.Position.Y < slice.Position.Y))
         {
             slice = currentSlice;
         }
     }
     return slice;
 }
Example #5
0
 protected int SortPool(PathGraphNode activeNode, PathGraphNode candidateNode1, PathGraphNode candidateNode2)
 {
     var result = (int)(candidateNode1.Position.Y - candidateNode2.Position.Y);
     if (result == 0)
     {
         result = candidateNode1.Edges.Count - candidateNode2.Edges.Count;
     }
     if (result == 0)
     {
         result = (int)(Vector3.DistanceSquared(candidateNode1.Position, activeNode.Position) -
                  Vector3.DistanceSquared(candidateNode2.Position, activeNode.Position));
     }
     return result;
 }
Example #6
0
 protected void InsertNodeIntoMaps(uint nodeId, int x, int z)
 {
     var height = m_getHeight(x, z);
     var node = new PathGraphNode(new Vector3(x, height, z), nodeId);
     if (height >= RiversStartMinHeight)
     {
         node.NodeType = PathNodeType.Source;
         m_sources.Add(nodeId, node);
     }
     else if (height <= RiverEndMaxHeight)
     {
         node.NodeType = PathNodeType.Sink;
         m_sinks.Add(nodeId, node);
     }
     else
     {
         node.NodeType = PathNodeType.General;
         m_general.Add(nodeId, node);
     }
 }
Example #7
0
 protected bool FilterPool(PathGraphNode activeNode, PathGraphNode candidateNode)
 {
     return activeNode != candidateNode && candidateNode.Position.Y <= activeNode.Position.Y && !activeNode.Edges.ContainsKey(candidateNode) && Vector3.DistanceSquared(candidateNode.Position, activeNode.Position) <= 625;
 }