summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs
diff options
context:
space:
mode:
authorchai <215380520@qq.com>2024-05-23 10:08:29 +0800
committerchai <215380520@qq.com>2024-05-23 10:08:29 +0800
commit8722a9920c1f6119bf6e769cba270e63097f8e25 (patch)
tree2eaf9865de7fb1404546de4a4296553d8f68cc3b /Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs
parent3ba4020b69e5971bb0df7ee08b31d10ea4d01937 (diff)
+ astar project
Diffstat (limited to 'Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs')
-rw-r--r--Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs220
1 files changed, 220 insertions, 0 deletions
diff --git a/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs
new file mode 100644
index 0000000..852fae8
--- /dev/null
+++ b/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/Graphs/Nodes/PointNode.cs
@@ -0,0 +1,220 @@
+using UnityEngine;
+using Pathfinding.Serialization;
+
+namespace Pathfinding {
+ /// <summary>
+ /// Node used for the PointGraph.
+ /// This is just a simple point with a list of connections (and associated costs) to other nodes.
+ /// It does not have any concept of a surface like many other node types.
+ ///
+ /// See: PointGraph
+ /// </summary>
+ public class PointNode : GraphNode {
+ /// <summary>
+ /// All connections from this node.
+ /// See: <see cref="Connect"/>
+ /// See: <see cref="Disconnect"/>
+ ///
+ /// Note: If you modify this array or the contents of it you must call <see cref="SetConnectivityDirty"/>.
+ ///
+ /// Note: If you modify this array or the contents of it you must call <see cref="PointGraph.RegisterConnectionLength"/> with the length of the new connections.
+ /// </summary>
+ public Connection[] connections;
+
+ /// <summary>
+ /// GameObject this node was created from (if any).
+ /// Warning: When loading a graph from a saved file or from cache, this field will be null.
+ ///
+ /// <code>
+ /// var node = AstarPath.active.GetNearest(transform.position).node;
+ /// var pointNode = node as PointNode;
+ ///
+ /// if (pointNode != null) {
+ /// Debug.Log("That node was created from the GameObject named " + pointNode.gameObject.name);
+ /// } else {
+ /// Debug.Log("That node is not a PointNode");
+ /// }
+ /// </code>
+ /// </summary>
+ public GameObject gameObject;
+
+ public void SetPosition (Int3 value) {
+ position = value;
+ }
+
+ public PointNode() { }
+ public PointNode (AstarPath astar) {
+ astar.InitializeNode(this);
+ }
+
+ /// <summary>
+ /// Closest point on the surface of this node to the point p.
+ ///
+ /// For a point node this is always the node's <see cref="position"/> sicne it has no surface.
+ /// </summary>
+ public override Vector3 ClosestPointOnNode (Vector3 p) {
+ return (Vector3)this.position;
+ }
+
+ /// <summary>
+ /// Checks if point is inside the node when seen from above.
+ ///
+ /// Since point nodes have no surface area, this method always returns false.
+ /// </summary>
+ public override bool ContainsPoint (Vector3 point) {
+ return false;
+ }
+
+ /// <summary>
+ /// Checks if point is inside the node in graph space.
+ ///
+ /// Since point nodes have no surface area, this method always returns false.
+ /// </summary>
+ public override bool ContainsPointInGraphSpace (Int3 point) {
+ return false;
+ }
+
+ public override void GetConnections<T>(GetConnectionsWithData<T> action, ref T data, int connectionFilter) {
+ if (connections == null) return;
+ for (int i = 0; i < connections.Length; i++) if ((connections[i].shapeEdgeInfo & connectionFilter) != 0) action(connections[i].node, ref data);
+ }
+
+ public override void ClearConnections (bool alsoReverse) {
+ if (alsoReverse && connections != null) {
+ for (int i = 0; i < connections.Length; i++) {
+ connections[i].node.RemovePartialConnection(this);
+ }
+ }
+
+ connections = null;
+ AstarPath.active.hierarchicalGraph.AddDirtyNode(this);
+ }
+
+ public override bool ContainsOutgoingConnection (GraphNode node) {
+ if (connections == null) return false;
+ for (int i = 0; i < connections.Length; i++) if (connections[i].node == node && connections[i].isOutgoing) return true;
+ return false;
+ }
+
+ public override void AddPartialConnection (GraphNode node, uint cost, bool isOutgoing, bool isIncoming) {
+ if (node == null) throw new System.ArgumentNullException();
+
+ if (connections != null) {
+ for (int i = 0; i < connections.Length; i++) {
+ if (connections[i].node == node) {
+ connections[i].cost = cost;
+ connections[i].shapeEdgeInfo = Connection.PackShapeEdgeInfo(isOutgoing, isIncoming);
+ return;
+ }
+ }
+ }
+
+ int connLength = connections != null ? connections.Length : 0;
+
+ var newconns = new Connection[connLength+1];
+ for (int i = 0; i < connLength; i++) {
+ newconns[i] = connections[i];
+ }
+
+ newconns[connLength] = new Connection(node, cost, isOutgoing, isIncoming);
+
+ connections = newconns;
+ AstarPath.active.hierarchicalGraph.AddDirtyNode(this);
+
+ // Make sure the graph knows that there exists a connection with this length
+ if (this.Graph is PointGraph pg) pg.RegisterConnectionLength((node.position - position).sqrMagnitudeLong);
+ }
+
+ public override void RemovePartialConnection (GraphNode node) {
+ if (connections == null) return;
+
+ for (int i = 0; i < connections.Length; i++) {
+ if (connections[i].node == node) {
+ int connLength = connections.Length;
+
+ var newconns = new Connection[connLength-1];
+ for (int j = 0; j < i; j++) {
+ newconns[j] = connections[j];
+ }
+ for (int j = i+1; j < connLength; j++) {
+ newconns[j-1] = connections[j];
+ }
+
+ connections = newconns;
+ AstarPath.active.hierarchicalGraph.AddDirtyNode(this);
+ return;
+ }
+ }
+ }
+
+ public override void Open (Path path, uint pathNodeIndex, uint gScore) {
+ path.OpenCandidateConnectionsToEndNode(position, pathNodeIndex, pathNodeIndex, gScore);
+
+ if (connections == null) return;
+
+ for (int i = 0; i < connections.Length; i++) {
+ GraphNode other = connections[i].node;
+
+ if (connections[i].isOutgoing && path.CanTraverse(this, other)) {
+ if (other is PointNode) {
+ path.OpenCandidateConnection(pathNodeIndex, other.NodeIndex, gScore, connections[i].cost, 0, other.position);
+ } else {
+ // When connecting to a non-point node, use a special function to open the connection.
+ // The typical case for this is that we are at the end of an off-mesh link and we are connecting to a navmesh node.
+ // In that case, this node's position is in the interior of the navmesh node. We let the navmesh node decide how
+ // that should be handled.
+ other.OpenAtPoint(path, pathNodeIndex, position, gScore);
+ }
+ }
+ }
+ }
+
+ public override void OpenAtPoint (Path path, uint pathNodeIndex, Int3 pos, uint gScore) {
+ if (path.CanTraverse(this)) {
+ // TODO: Ideally we should only allow connections to the temporary end node directly from the temporary start node
+ // iff they lie on the same connection edge. Otherwise we need to pass through the center of this node.
+ //
+ // N1---E----N2
+ // | /
+ // | /
+ // S
+ // |
+ // N3
+ //
+ path.OpenCandidateConnectionsToEndNode(pos, pathNodeIndex, pathNodeIndex, gScore);
+
+ var cost = (uint)(pos - this.position).costMagnitude;
+ path.OpenCandidateConnection(pathNodeIndex, NodeIndex, gScore, cost, 0, position);
+ }
+ }
+
+ public override int GetGizmoHashCode () {
+ var hash = base.GetGizmoHashCode();
+
+ if (connections != null) {
+ for (int i = 0; i < connections.Length; i++) {
+ hash ^= 17 * connections[i].GetHashCode();
+ }
+ }
+ return hash;
+ }
+
+ public override void SerializeNode (GraphSerializationContext ctx) {
+ base.SerializeNode(ctx);
+ ctx.SerializeInt3(position);
+ }
+
+ public override void DeserializeNode (GraphSerializationContext ctx) {
+ base.DeserializeNode(ctx);
+ position = ctx.DeserializeInt3();
+ }
+
+ public override void SerializeReferences (GraphSerializationContext ctx) {
+ ctx.SerializeConnections(connections, true);
+ }
+
+ public override void DeserializeReferences (GraphSerializationContext ctx) {
+ connections = ctx.DeserializeConnections(ctx.meta.version >= AstarSerializer.V4_3_85);
+ }
+ }
+}