123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- using UnityEngine;
- using Pathfinding.Serialization;
- namespace Pathfinding {
-
- public interface INavmeshHolder : ITransformedGraph, INavmesh {
-
- Int3 GetVertex(int i);
-
-
-
-
- Int3 GetVertexInGraphSpace(int i);
- int GetVertexArrayIndex(int index);
-
- void GetTileCoordinates(int tileIndex, out int x, out int z);
- }
-
- public class TriangleMeshNode : MeshNode {
- public TriangleMeshNode (AstarPath astar) : base(astar) {}
-
- public int v0;
-
- public int v1;
-
- public int v2;
-
- protected static INavmeshHolder[] _navmeshHolders = new INavmeshHolder[0];
-
- protected static readonly System.Object lockObject = new System.Object();
- public static INavmeshHolder GetNavmeshHolder (uint graphIndex) {
- return _navmeshHolders[(int)graphIndex];
- }
-
-
-
-
- public static void SetNavmeshHolder (int graphIndex, INavmeshHolder graph) {
-
-
- lock (lockObject) {
- if (graphIndex >= _navmeshHolders.Length) {
- var gg = new INavmeshHolder[graphIndex+1];
- _navmeshHolders.CopyTo(gg, 0);
- _navmeshHolders = gg;
- }
- _navmeshHolders[graphIndex] = graph;
- }
- }
-
- public void UpdatePositionFromVertices () {
- Int3 a, b, c;
- GetVertices(out a, out b, out c);
- position = (a + b + c) * 0.333333f;
- }
-
-
-
-
-
- public int GetVertexIndex (int i) {
- return i == 0 ? v0 : (i == 1 ? v1 : v2);
- }
-
-
-
-
-
- public int GetVertexArrayIndex (int i) {
- return GetNavmeshHolder(GraphIndex).GetVertexArrayIndex(i == 0 ? v0 : (i == 1 ? v1 : v2));
- }
-
- public void GetVertices (out Int3 v0, out Int3 v1, out Int3 v2) {
-
-
- var holder = GetNavmeshHolder(GraphIndex);
- v0 = holder.GetVertex(this.v0);
- v1 = holder.GetVertex(this.v1);
- v2 = holder.GetVertex(this.v2);
- }
-
- public void GetVerticesInGraphSpace (out Int3 v0, out Int3 v1, out Int3 v2) {
-
-
- var holder = GetNavmeshHolder(GraphIndex);
- v0 = holder.GetVertexInGraphSpace(this.v0);
- v1 = holder.GetVertexInGraphSpace(this.v1);
- v2 = holder.GetVertexInGraphSpace(this.v2);
- }
- public override Int3 GetVertex (int i) {
- return GetNavmeshHolder(GraphIndex).GetVertex(GetVertexIndex(i));
- }
- public Int3 GetVertexInGraphSpace (int i) {
- return GetNavmeshHolder(GraphIndex).GetVertexInGraphSpace(GetVertexIndex(i));
- }
- public override int GetVertexCount () {
-
- return 3;
- }
- public override Vector3 ClosestPointOnNode (Vector3 p) {
- Int3 a, b, c;
- GetVertices(out a, out b, out c);
- return Pathfinding.Polygon.ClosestPointOnTriangle((Vector3)a, (Vector3)b, (Vector3)c, p);
- }
-
-
-
-
-
-
-
-
-
-
-
-
- internal Int3 ClosestPointOnNodeXZInGraphSpace (Vector3 p) {
-
- Int3 a, b, c;
- GetVerticesInGraphSpace(out a, out b, out c);
-
- p = GetNavmeshHolder(GraphIndex).transform.InverseTransform(p);
-
- var closest = Pathfinding.Polygon.ClosestPointOnTriangleXZ((Vector3)a, (Vector3)b, (Vector3)c, p);
-
- var i3closest = (Int3)closest;
- if (ContainsPointInGraphSpace(i3closest)) {
-
- return i3closest;
- } else {
-
-
-
-
-
-
-
- for (int dx = -1; dx <= 1; dx++) {
- for (int dz = -1; dz <= 1; dz++) {
- if ((dx != 0 || dz != 0)) {
- var candidate = new Int3(i3closest.x + dx, i3closest.y, i3closest.z + dz);
- if (ContainsPointInGraphSpace(candidate)) return candidate;
- }
- }
- }
-
-
-
- var da = (a - i3closest).sqrMagnitudeLong;
- var db = (b - i3closest).sqrMagnitudeLong;
- var dc = (c - i3closest).sqrMagnitudeLong;
- return da < db ? (da < dc ? a : c) : (db < dc ? b : c);
- }
- }
- public override Vector3 ClosestPointOnNodeXZ (Vector3 p) {
-
- Int3 tp1, tp2, tp3;
- GetVertices(out tp1, out tp2, out tp3);
- return Polygon.ClosestPointOnTriangleXZ((Vector3)tp1, (Vector3)tp2, (Vector3)tp3, p);
- }
- public override bool ContainsPoint (Vector3 p) {
- return ContainsPointInGraphSpace((Int3)GetNavmeshHolder(GraphIndex).transform.InverseTransform(p));
- }
- public override bool ContainsPointInGraphSpace (Int3 p) {
-
- Int3 a, b, c;
- GetVerticesInGraphSpace(out a, out b, out c);
- if ((long)(b.x - a.x) * (long)(p.z - a.z) - (long)(p.x - a.x) * (long)(b.z - a.z) > 0) return false;
- if ((long)(c.x - b.x) * (long)(p.z - b.z) - (long)(p.x - b.x) * (long)(c.z - b.z) > 0) return false;
- if ((long)(a.x - c.x) * (long)(p.z - c.z) - (long)(p.x - c.x) * (long)(a.z - c.z) > 0) return false;
- return true;
-
-
-
- }
- public override void UpdateRecursiveG (Path path, PathNode pathNode, PathHandler handler) {
- pathNode.UpdateG(path);
- handler.heap.Add(pathNode);
- if (connections == null) return;
- for (int i = 0; i < connections.Length; i++) {
- GraphNode other = connections[i].node;
- PathNode otherPN = handler.GetPathNode(other);
- if (otherPN.parent == pathNode && otherPN.pathID == handler.PathID) other.UpdateRecursiveG(path, otherPN, handler);
- }
- }
- public override void Open (Path path, PathNode pathNode, PathHandler handler) {
- if (connections == null) return;
-
-
- bool flag2 = pathNode.flag2;
-
- for (int i = connections.Length-1; i >= 0; i--) {
- var conn = connections[i];
- var other = conn.node;
-
- if (path.CanTraverse(conn.node)) {
- PathNode pathOther = handler.GetPathNode(conn.node);
-
- if (pathOther == pathNode.parent) {
- continue;
- }
- uint cost = conn.cost;
- if (flag2 || pathOther.flag2) {
-
-
- cost = path.GetConnectionSpecialCost(this, conn.node, cost);
- }
-
- if (pathOther.pathID != handler.PathID) {
-
-
-
-
- pathOther.node = conn.node;
- pathOther.parent = pathNode;
- pathOther.pathID = handler.PathID;
- pathOther.cost = cost;
- pathOther.H = path.CalculateHScore(other);
- pathOther.UpdateG(path);
- handler.heap.Add(pathOther);
- } else {
-
- if (pathNode.G + cost + path.GetTraversalCost(other) < pathOther.G) {
- pathOther.cost = cost;
- pathOther.parent = pathNode;
- other.UpdateRecursiveG(path, pathOther, handler);
- }
- }
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public int SharedEdge (GraphNode other) {
- var edge = -1;
- if (connections != null) {
- for (int i = 0; i < connections.Length; i++) {
- if (connections[i].node == other) edge = connections[i].shapeEdge;
- }
- }
- return edge;
- }
- public override bool GetPortal (GraphNode toNode, System.Collections.Generic.List<Vector3> left, System.Collections.Generic.List<Vector3> right, bool backwards) {
- int aIndex, bIndex;
- return GetPortal(toNode, left, right, backwards, out aIndex, out bIndex);
- }
- public bool GetPortal (GraphNode toNode, System.Collections.Generic.List<Vector3> left, System.Collections.Generic.List<Vector3> right, bool backwards, out int aIndex, out int bIndex) {
- aIndex = -1;
- bIndex = -1;
-
- if (backwards || toNode.GraphIndex != GraphIndex) return false;
-
-
- var toTriNode = toNode as TriangleMeshNode;
- var edge = SharedEdge(toTriNode);
-
- if (edge == Connection.NoSharedEdge) return false;
-
-
- if (edge == -1) {
- #if !ASTAR_NO_POINT_GRAPH
- if (connections != null) {
- for (int i = 0; i < connections.Length; i++) {
- if (connections[i].node.GraphIndex != GraphIndex) {
- var mid = connections[i].node as NodeLink3Node;
- if (mid != null && mid.GetOther(this) == toTriNode) {
-
- mid.GetPortal(toTriNode, left, right, false);
- return true;
- }
- }
- }
- }
- #endif
- return false;
- }
- aIndex = edge;
- bIndex = (edge + 1) % GetVertexCount();
-
- Int3 v1a = GetVertex(edge);
- Int3 v1b = GetVertex((edge+1) % GetVertexCount());
-
- int tileIndex1 = (GetVertexIndex(0) >> NavmeshBase.TileIndexOffset) & NavmeshBase.TileIndexMask;
- int tileIndex2 = (toTriNode.GetVertexIndex(0) >> NavmeshBase.TileIndexOffset) & NavmeshBase.TileIndexMask;
- if (tileIndex1 != tileIndex2) {
-
-
-
- int x1, x2, z1, z2, coord;
- INavmeshHolder nm = GetNavmeshHolder(GraphIndex);
- nm.GetTileCoordinates(tileIndex1, out x1, out z1);
- nm.GetTileCoordinates(tileIndex2, out x2, out z2);
- if (System.Math.Abs(x1-x2) == 1) coord = 2;
- else if (System.Math.Abs(z1-z2) == 1) coord = 0;
- else return false;
- var otherEdge = toTriNode.SharedEdge(this);
-
- if (otherEdge == Connection.NoSharedEdge) throw new System.Exception("Connection used edge in one direction, but not in the other direction. Has the wrong overload of AddConnection been used?");
-
- if (otherEdge != -1) {
-
-
- int mincoord = System.Math.Min(v1a[coord], v1b[coord]);
- int maxcoord = System.Math.Max(v1a[coord], v1b[coord]);
-
- Int3 v2a = toTriNode.GetVertex(otherEdge);
- Int3 v2b = toTriNode.GetVertex((otherEdge+1) % toTriNode.GetVertexCount());
- mincoord = System.Math.Max(mincoord, System.Math.Min(v2a[coord], v2b[coord]));
- maxcoord = System.Math.Min(maxcoord, System.Math.Max(v2a[coord], v2b[coord]));
- if (v1a[coord] < v1b[coord]) {
- v1a[coord] = mincoord;
- v1b[coord] = maxcoord;
- } else {
- v1a[coord] = maxcoord;
- v1b[coord] = mincoord;
- }
- }
- }
- if (left != null) {
-
- left.Add((Vector3)v1a);
- right.Add((Vector3)v1b);
- }
- return true;
- }
-
- public override float SurfaceArea () {
- var holder = GetNavmeshHolder(GraphIndex);
- return System.Math.Abs(VectorMath.SignedTriangleAreaTimes2XZ(holder.GetVertex(v0), holder.GetVertex(v1), holder.GetVertex(v2))) * 0.5f;
- }
- public override Vector3 RandomPointOnSurface () {
-
-
-
- float r1;
- float r2;
- do {
- r1 = Random.value;
- r2 = Random.value;
- } while (r1+r2 > 1);
- var holder = GetNavmeshHolder(GraphIndex);
-
- return ((Vector3)(holder.GetVertex(v1)-holder.GetVertex(v0)))*r1 + ((Vector3)(holder.GetVertex(v2)-holder.GetVertex(v0)))*r2 + (Vector3)holder.GetVertex(v0);
- }
- public override void SerializeNode (GraphSerializationContext ctx) {
- base.SerializeNode(ctx);
- ctx.writer.Write(v0);
- ctx.writer.Write(v1);
- ctx.writer.Write(v2);
- }
- public override void DeserializeNode (GraphSerializationContext ctx) {
- base.DeserializeNode(ctx);
- v0 = ctx.reader.ReadInt32();
- v1 = ctx.reader.ReadInt32();
- v2 = ctx.reader.ReadInt32();
- }
- }
- }
|