public int InsertAbstractNode(HierarchicalMap map, Position pos, int start)
		{
			var nodeId = pos.Y * map.Width + pos.X;
			var result = InsertStal(map, nodeId, pos, start);
			InsertStalHEdges(map, nodeId);
			return result;
		}
        public int EntranceLocalIdx { get; set; } // local id

        public LocalEntrance(int nodeId, int absNodeId, int localIdx, Position relativePosition)
        {
            Id = nodeId;
            AbsNodeId = absNodeId;
            EntranceLocalIdx = localIdx;
            RelativePos = relativePosition;
        }
 public AbsTilingNodeInfo(int id, int level, int clId,
             Position position, int centerId,
             int localIdxCluster)
 {
     Id = id;
     Level = level;
     ClusterId = clId;
     Position = position;
     CenterId = centerId;
     LocalIdxCluster = localIdxCluster;
 }
 public AbsTilingNodeInfo(int id, int level, int clId,
             Position position, int centerId,
             int localEntranceId)
 {
     Id = id;
     Level = level;
     ClusterId = clId;
     Position = position;
     CenterId = centerId;
     this.LocalEntranceId = localEntranceId;
 }
        public Position Origin { get; set; } // The position where this cluster starts in the main grid

        public Cluster(ConcreteMap concreteMap, int id, int clusterX, int clusterY, Position origin, Size size)
        {
            SubConcreteMap = concreteMap.Slice(origin.X, origin.Y, size.Width, size.Height, concreteMap.Passability);
            Id = id;
            ClusterY = clusterY;
            ClusterX = clusterX;
            Origin = origin;
            Size = size;
            Distances = new Dictionary<Tuple<int, int>, int>();
			CachedPaths = new Dictionary<Tuple<int, int>, List<int>>();
			DistanceCalculated = new Dictionary<Tuple<int, int>, bool>();
            EntrancePoints = new List<EntrancePoint>();
        }
 public static bool AreAligned(Position p1, Position p2)
 {
     return p1.X == p2.X || p1.Y == p2.Y;
 }
 public TilingNodeInfo(bool isObstacle, int cost, Position position)
 {
     IsObstacle = isObstacle;
     Position = position;
     Cost = cost;
 }
        /// <summary>
        /// Tells whether we can move from p1 to p2 in line. Bear in mind
        /// this function does not consider intermediate points (it is
        /// assumed you can jump between intermediate points)
        /// </summary>
        public bool CanJump(Position p1, Position p2)
        {
            if (TileType != TileType.OCTILE && this.TileType != TileType.OCTILE_UNICOST)
                return true;
            if (Helpers.AreAligned(p1, p2))
                return true;

			// The following piece of code existed in the original implementation.
			// It basically checks that you do not forcefully cross a blocked diagonal.
			// Honestly, this is weird, bad designed and supposes that each position is adjacent to each other.
            var nodeInfo12 = Graph.GetNode(GetNodeIdFromPos(p2.X, p1.Y)).Info;
            var nodeInfo21 = Graph.GetNode(GetNodeIdFromPos(p1.X, p2.Y)).Info;
            return !(nodeInfo12.IsObstacle && nodeInfo21.IsObstacle);
        }
		// insert a new node, such as start or target, to the abstract graph and
		// returns the id of the newly created node in the abstract graph
		// x and y are the positions where I want to put the node
		private int InsertStal(HierarchicalMap map, int nodeId, Position pos, int start)
		{
			// If the node already existed (for instance, it was the an entrance point already
			// existing in the graph, we need to keep track of the previous status in order
			// to be able to restore it once we delete this STAL
			if (map.AbsNodeIds[nodeId] != Constants.NO_NODE)
			{
				m_stalLevel[start] = map.AbstractGraph.GetNodeInfo(map.AbsNodeIds[nodeId]).Level;
				m_stalEdges[start] = map.GetNodeEdges(nodeId);
				m_stalUsed[start] = true;
				return map.AbsNodeIds[nodeId];
			}

			m_stalUsed[start] = false;

			var cluster = map.FindClusterForPosition(pos);

			// create global entrance
			var absNodeId = map.NrNodes;
			var localEntranceIdx = cluster.AddEntrance(absNodeId, new Position(pos.X - cluster.Origin.X, pos.Y - cluster.Origin.Y));
			cluster.UpdatePaths(localEntranceIdx);

			map.AbsNodeIds[nodeId] = absNodeId;

			var info = new AbsTilingNodeInfo(
				absNodeId,
				1,
				cluster.Id,
				pos,
				nodeId,
				localEntranceIdx);

			map.AbstractGraph.AddNode(absNodeId, info);

			// add new edges to the abstract graph
			for (var k = 0; k < cluster.GetNrEntrances() - 1; k++)
			{
				if (cluster.AreConnected(localEntranceIdx, k))
				{
					map.AddEdge(
						cluster.GetGlobalAbsNodeId(k),
						cluster.GetGlobalAbsNodeId(localEntranceIdx),
						cluster.GetDistance(localEntranceIdx, k));
					map.AddEdge(
						cluster.GetGlobalAbsNodeId(localEntranceIdx),
						cluster.GetGlobalAbsNodeId(k),
						cluster.GetDistance(k, localEntranceIdx));
				}
			}

			return absNodeId;
		}
Beispiel #10
0
			public bool CanEnter(Position pos, out int cost)
			{
				cost = Constants.COST_ONE;
				return !obstacles[pos.X, pos.Y];
			}
Beispiel #11
0
		public int EntranceLocalIdx { get; set; } // local id

		public EntrancePoint(int absNodeId, int localIdx, Position relativePosition)
		{
			AbsNodeId = absNodeId;
			EntranceLocalIdx = localIdx;
			RelativePos = relativePosition;
		}
Beispiel #12
0
 /// <summary>
 /// Adds an entrance point to the cluster and returns the entrance index assigned for the point
 /// </summary>
 public int AddEntrance(int abstractNodeId, Position relativePosition)
 {
     var entranceLocalIdx = EntrancePoints.Count;
     var localEntrance = new EntrancePoint(
         abstractNodeId,
         EntrancePoints.Count,
         relativePosition);
     EntrancePoints.Add(localEntrance);
     return entranceLocalIdx;
 }
		/// <summary>
		/// Defines the bounding box of the cluster we want to process based on a given level and a position in the grid
		/// </summary>
		public void SetCurrentCluster(Position pos, int level)
		{
			// if the level surpasses the MaxLevel, just set the whole map as a cluster
			if (level > MaxLevel)
			{
				this.currentClusterY0 = 0;
				this.currentClusterY1 = this.Height - 1;
				this.currentClusterX0 = 0;
				this.currentClusterX1 = this.Width - 1;
				return;
			}

			var offset = GetOffset(level);
			var nodeY = pos.Y; // nodeId / this.Width;
			var nodeX = pos.X; // nodeId % this.Width;
			this.currentClusterY0 = nodeY - (nodeY % offset);
			this.currentClusterY1 = Math.Min(this.Height - 1, this.currentClusterY0 + offset - 1);
			this.currentClusterX0 = nodeX - (nodeX % offset);
			this.currentClusterX1 = Math.Min(this.Width - 1, this.currentClusterX0 + offset - 1);
		}
		public bool PositionInCurrentCluster(Position position)
		{
			var y = position.Y;
			var x = position.X;
			return y >= this.currentClusterY0 && y <= this.currentClusterY1 && x >= this.currentClusterX0 && x <= this.currentClusterX1;
		}
		public Cluster FindClusterForPosition(Position pos)
        {
            var cluster = this.Clusters
                .First(cl =>
                    cl.Origin.Y <= pos.Y &&
                    pos.Y < cl.Origin.Y + cl.Size.Height &&
                    cl.Origin.X <= pos.X &&
                    pos.X < cl.Origin.X + cl.Size.Width);
            return cluster;
        }