Exemplo n.º 1
0
		/** Calculates the grid connections for a single node */
		public virtual void CalculateConnections (GridNode[] nodes, int x, int z, GridNode node) {
			
			//Reset all connections
			//node.flags = node.lags & -256;
			
			node.ResetConnectionsInternal ();
			
			//All connections are disabled if the node is not walkable
			if (!node.Walkable) {
				return;
			}
			
			int index = node.NodeInGridIndex;
			
			if (corners == null) {
				corners = new int[4];
			} else {
				for (int i = 0;i<4;i++) {
					corners[i] = 0;
				}
			}
			
			for (int i=0, j = 3; i<4; j = i, i++) {
				
				int nx = x + neighbourXOffsets[i];
				int nz = z + neighbourZOffsets[i];
				
				if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
					continue;
				}
				
				GridNode other = nodes[index+neighbourOffsets[i]] as GridNode;
				
				if (IsValidConnection (node, other)) {
					node.SetConnectionInternal (i, true);
					//SetNodeConnection (node, i, true);
					corners[i]++;
					corners[j]++;
				} else {
					node.SetConnectionInternal (i, false);
					//SetNodeConnection (node, i, false);
				}
			}
			
			if (neighbours == NumNeighbours.Eight) {
				if (cutCorners) {
					for (int i=0; i<4; i++) {
						
						if (corners[i] >= 1) {
							int nx = x + neighbourXOffsets[i+4];
							int nz = z + neighbourZOffsets[i+4];
						
							if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
								continue;
							}
					
							GridNode other = nodes[index+neighbourOffsets[i+4]];
							
							node.SetConnectionInternal (i+4, IsValidConnection (node,other));
							//SetNodeConnection (node, i+4, IsValidConnection (node,other));
						}
					}
				} else {
					for (int i=0; i<4; i++) {
						
						//We don't need to check if it is out of bounds because if both of the other neighbours are inside the bounds this one must be too
						if (corners[i] == 2) {
							GridNode other = nodes[index+neighbourOffsets[i+4]];
							
							node.SetConnectionInternal (i+4, IsValidConnection (node,other));
							//SetNodeConnection (node, i+4, IsValidConnection (node,other));
						}
					}
				}
			}
			
		}
Exemplo n.º 2
0
		/** Calculates the grid connections for a single node */
		public virtual void CalculateConnections (GridNode[] nodes, int x, int z, GridNode node) {
			
			//Reset all connections
			// This makes the node have NO connections to any neighbour nodes
			node.ResetConnectionsInternal ();
			
			//All connections are disabled if the node is not walkable
			if (!node.Walkable) {
				return;
			}

			// Internal index of where in the graph the node is
			int index = node.NodeInGridIndex;

			if (corners == null) {
				corners = new int[4];
			} else {
				for (int i = 0;i<4;i++) {
					corners[i] = 0;
				}
			}

			// Loop through axis aligned neighbours (up, down, right, left)
			for (int i=0, j = 3; i<4; j = i, i++) {
				
				int nx = x + neighbourXOffsets[i];
				int nz = z + neighbourZOffsets[i];
				
				if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
					continue;
				}
				
				GridNode other = nodes[index+neighbourOffsets[i]] as GridNode;
				
				if (IsValidConnection (node, other)) {
					node.SetConnectionInternal (i, true);
					corners[i]++;
					corners[j]++;
				} else {
					node.SetConnectionInternal (i, false);
				}
			}

			// Add in the diagonal connections
			if (neighbours == NumNeighbours.Eight) {
				if (cutCorners) {
					for (int i=0; i<4; i++) {
						
						if (corners[i] >= 1) {
							int nx = x + neighbourXOffsets[i+4];
							int nz = z + neighbourZOffsets[i+4];
						
							if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
								continue;
							}
					
							GridNode other = nodes[index+neighbourOffsets[i+4]];
							
							node.SetConnectionInternal (i+4, IsValidConnection (node,other));
						}
					}
				} else {
					for (int i=0; i<4; i++) {
						
						//We don't need to check if it is out of bounds because if both of the other neighbours are inside the bounds this one must be too
						if (corners[i] == 2) {
							GridNode other = nodes[index+neighbourOffsets[i+4]];
							
							node.SetConnectionInternal (i+4, IsValidConnection (node,other));
						}
					}
				}
			}
			
		}
Exemplo n.º 3
0
		/** Calculates the grid connections for a single node.
		 * The x and z parameters are assumed to be the grid coordinates of the node.
		 *
		 * \see CalculateConnections(GridNode)
		 */
		public virtual void CalculateConnections (int x, int z, GridNode node) {
			// All connections are disabled if the node is not walkable
			if (!node.Walkable) {
				// Reset all connections
				// This makes the node have NO connections to any neighbour nodes
				node.ResetConnectionsInternal();
				return;
			}

			// Internal index of where in the graph the node is
			int index = node.NodeInGridIndex;

			if (neighbours == NumNeighbours.Four || neighbours == NumNeighbours.Eight) {
				// Bitpacked connections
				// bit 0 is set if connection 0 is enabled
				// bit 1 is set if connection 1 is enabled etc.
				int conns = 0;

				// Loop through axis aligned neighbours (down, right, up, left) or (-Z, +X, +Z, -X)
				for (int i = 0; i < 4; i++) {
					int nx = x + neighbourXOffsets[i];
					int nz = z + neighbourZOffsets[i];

					// Check if the new position is inside the grid
					// Bitwise AND (&) is measurably faster than &&
					// (not much, but this code is hot)
					if (nx >= 0 & nz >= 0 & nx < width & nz < depth) {
						var other = nodes[index+neighbourOffsets[i]];

						if (IsValidConnection(node, other)) {
							// Enable connection i
							conns |= 1 << i;
						}
					}
				}

				// Bitpacked diagonal connections
				int diagConns = 0;

				// Add in the diagonal connections
				if (neighbours == NumNeighbours.Eight) {
					if (cutCorners) {
						for (int i = 0; i < 4; i++) {
							// If at least one axis aligned connection
							// is adjacent to this diagonal, then we can add a connection.
							// Bitshifting is a lot faster than calling node.GetConnectionInternal.
							// We need to check if connection i and i+1 are enabled
							// but i+1 may overflow 4 and in that case need to be wrapped around
							// (so 3+1 = 4 goes to 0). We do that by checking both connection i+1
							// and i+1-4 at the same time. Either i+1 or i+1-4 will be in the range
							// from 0 to 4 (exclusive)
							if (((conns >> i | conns >> (i+1) | conns >> (i+1-4)) & 1) != 0) {
								int directionIndex = i+4;

								int nx = x + neighbourXOffsets[directionIndex];
								int nz = z + neighbourZOffsets[directionIndex];

								if (nx >= 0 & nz >= 0 & nx < width & nz < depth) {
									GridNode other = nodes[index+neighbourOffsets[directionIndex]];

									if (IsValidConnection(node, other)) {
										diagConns |= 1 << directionIndex;
									}
								}
							}
						}
					} else {
						for (int i = 0; i < 4; i++) {
							// If exactly 2 axis aligned connections is adjacent to this connection
							// then we can add the connection
							// We don't need to check if it is out of bounds because if both of
							// the other neighbours are inside the bounds this one must be too
							if ((conns >> i & 1) != 0 && ((conns >> (i+1) | conns >> (i+1-4)) & 1) != 0) {
								GridNode other = nodes[index+neighbourOffsets[i+4]];

								if (IsValidConnection(node, other)) {
									diagConns |= 1 << (i+4);
								}
							}
						}
					}
				}

				// Set all connections at the same time
				node.SetAllConnectionInternal(conns | diagConns);
			} else {
				// Hexagon layout

				// Reset all connections
				// This makes the node have NO connections to any neighbour nodes
				node.ResetConnectionsInternal();

				// Loop through all possible neighbours and try to connect to them
				for (int j = 0; j < hexagonNeighbourIndices.Length; j++) {
					var i = hexagonNeighbourIndices[j];

					int nx = x + neighbourXOffsets[i];
					int nz = z + neighbourZOffsets[i];

					if (nx >= 0 & nz >= 0 & nx < width & nz < depth) {
						var other = nodes[index+neighbourOffsets[i]];
						node.SetConnectionInternal(i, IsValidConnection(node, other));
					}
				}
			}
		}
		/** Calculates the grid connections for a single node */
		public virtual void CalculateConnections (GridNode[] nodes, int x, int z, GridNode node) {

			//Reset all connections
			// This makes the node have NO connections to any neighbour nodes
			node.ResetConnectionsInternal ();

			//All connections are disabled if the node is not walkable
			if (!node.Walkable) {
				return;
			}

			// Internal index of where in the graph the node is
			int index = node.NodeInGridIndex;

			if (neighbours == NumNeighbours.Four || neighbours == NumNeighbours.Eight) {

				// Reset the buffer
				if (corners == null) {
					corners = new int[4];
				} else {
					for (int i = 0;i<4;i++) {
						corners[i] = 0;
					}
				}

				// Loop through axis aligned neighbours (up, down, right, left)
				for (int i=0, j = 3; i<4; j = i, i++) {

					int nx = x + neighbourXOffsets[i];
					int nz = z + neighbourZOffsets[i];

					if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
						continue;
					}

					var other = nodes[index+neighbourOffsets[i]];

					if (IsValidConnection (node, other)) {
						node.SetConnectionInternal (i, true);

						// Mark the diagonal/corner adjacent to this connection as used
						corners[i]++;
						corners[j]++;
					} else {
						node.SetConnectionInternal (i, false);
					}
				}

				// Add in the diagonal connections
				if (neighbours == NumNeighbours.Eight) {
					if (cutCorners) {
						for (int i=0; i<4; i++) {

							// If at least one axis aligned connection
							// is adjacent to this diagonal, then we can add a connection
							if (corners[i] >= 1) {
								int nx = x + neighbourXOffsets[i+4];
								int nz = z + neighbourZOffsets[i+4];

								if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
									continue;
								}

								GridNode other = nodes[index+neighbourOffsets[i+4]];

								node.SetConnectionInternal (i+4, IsValidConnection (node,other));
							}
						}
					} else {
						for (int i=0; i<4; i++) {

							// If exactly 2 axis aligned connections is adjacent to this connection
							// then we can add the connection
							//We don't need to check if it is out of bounds because if both of the other neighbours are inside the bounds this one must be too
							if (corners[i] == 2) {
								GridNode other = nodes[index+neighbourOffsets[i+4]];

								node.SetConnectionInternal (i+4, IsValidConnection (node,other));
							}
						}
					}
				}
			} else {
				// Hexagon layout

				// Loop through all possible neighbours and try to connect to them
				for (int j = 0; j < hexagonNeighbourIndices.Length; j++) {
					var i = hexagonNeighbourIndices[j];

					int nx = x + neighbourXOffsets[i];
					int nz = z + neighbourZOffsets[i];

					if (nx < 0 || nz < 0 || nx >= width || nz >= depth) {
						continue;
					}

					var other = nodes[index+neighbourOffsets[i]];

					node.SetConnectionInternal (i, IsValidConnection (node, other));
				}
			}
		}