/// <summary> /// Find the closest polygon possible in the tile under certain constraints. /// </summary> /// <param name="tile">Current tile</param> /// <param name="center">Center starting point</param> /// <param name="extents">Range of search</param> /// <param name="nearestPt">Resulting nearest point</param> /// <returns>Polygon Reference which contains nearest point</returns> public PolyId FindNearestPoly(Vector3 center, Vector3 extents, ref Vector3 nearestPt) { BBox3 bounds; bounds.Min = center - extents; bounds.Max = center + extents; //Get nearby polygons from proximity grid List <PolyId> polys = new List <PolyId>(128); int polyCount = this.QueryPolygons(bounds, polys); //Find nearest polygon amongst the nearby polygons PolyId nearest = PolyId.Null; float nearestDistanceSqr = float.MaxValue; //Iterate throuh all the polygons for (int i = 0; i < polyCount; i++) { PolyId reference = polys[i]; Vector3 closestPtPoly = new Vector3(); ClosestPointOnPoly(idManager.DecodePolyIndex(ref reference), center, ref closestPtPoly); float d = (center - closestPtPoly).LengthSquared(); if (d < nearestDistanceSqr) { nearestPt = closestPtPoly; nearestDistanceSqr = d; nearest = reference; } } return(nearest); }
public MeshTile(Vector2i location, int layer, PolyIdManager manager, PolyId baseRef) { this.Location = location; this.Layer = layer; this.idManager = manager; this.baseRef = baseRef; }
/// <summary> /// Begin creating off-mesh links between the tile polygons. /// </summary> public void BaseOffMeshLinks() { //Base off-mesh connection start points for (int i = 0; i < OffMeshConnectionCount; i++) { int con = i; OffMeshConnection omc = OffMeshConnections[con]; Vector3 extents = new Vector3(omc.Radius, WalkableClimb, omc.Radius); //Find polygon to connect to Vector3 p = omc.Pos0; Vector3 nearestPt = new Vector3(); PolyId reference = FindNearestPoly(p, extents, ref nearestPt); if (reference == PolyId.Null) { continue; } //Do extra checks if ((nearestPt.X - p.X) * (nearestPt.X - p.X) + (nearestPt.Z - p.Z) * (nearestPt.Z - p.Z) > OffMeshConnections[con].Radius * OffMeshConnections[con].Radius) { continue; } Poly poly = this.Polys[omc.Poly]; //Make sure location is on current mesh Verts[poly.Verts[0]] = nearestPt; Link link = new Link(); link.Reference = reference; link.Edge = 0; link.Side = BoundarySide.Internal; poly.Links.Add(link); //Start end-point always conects back to off-mesh connection int landPolyIdx = idManager.DecodePolyIndex(ref reference); PolyId id; idManager.SetPolyIndex(ref baseRef, OffMeshConnections[con].Poly, out id); Link link2 = new Link(); link2.Reference = id; link2.Edge = 0xff; link2.Side = BoundarySide.Internal; Polys[landPolyIdx].Links.Add(link2); } }
/// <summary> /// Initializes a new instance of the <see cref="NavPoint"/> struct. /// </summary> /// <param name="poly">The polygon that the point is on.</param> /// <param name="pos">The 3d position of the point.</param> public NavPoint(PolyId poly, Vector3 pos) { this.Polygon = poly; this.Position = pos; }
/// <summary> /// Connect Off-Mesh links between polygons from two different tiles. /// </summary> /// <param name="target">Target Tile</param> /// <param name="side">Polygon edge</param> public void ConnectExtOffMeshLinks(MeshTile target, BoundarySide side) { //Connect off-mesh links, specifically links which land from target tile to this tile BoundarySide oppositeSide = side.GetOpposite(); //Iterate through all the off-mesh connections of target tile for (int i = 0; i < target.OffMeshConnectionCount; i++) { OffMeshConnection targetCon = target.OffMeshConnections[i]; if (targetCon.Side != oppositeSide) { continue; } Poly targetPoly = target.Polys[targetCon.Poly]; //Skip off-mesh connections which start location could not be connected at all if (targetPoly.Links.Count == 0) { continue; } Vector3 extents = new Vector3(targetCon.Radius, target.WalkableClimb, targetCon.Radius); //Find polygon to connect to Vector3 p = targetCon.Pos1; Vector3 nearestPt = new Vector3(); PolyId reference = FindNearestPoly(p, extents, ref nearestPt); if (reference == PolyId.Null) { continue; } //Further checks if ((nearestPt.X - p.X) * (nearestPt.X - p.X) + (nearestPt.Z - p.Z) * (nearestPt.Z - p.Z) > (targetCon.Radius * targetCon.Radius)) { continue; } //Make sure the location is on the current mesh target.Verts[targetPoly.Verts[1]] = nearestPt; //Link off-mesh connection to target poly Link link = new Link(); link.Reference = reference; link.Edge = i; link.Side = oppositeSide; target.Polys[i].Links.Add(link); //link target poly to off-mesh connection if ((targetCon.Flags & OffMeshConnectionFlags.Bidirectional) != 0) { int landPolyIdx = idManager.DecodePolyIndex(ref reference); PolyId id; id = target.baseRef; idManager.SetPolyIndex(ref id, targetCon.Poly, out id); Link bidiLink = new Link(); bidiLink.Reference = id; bidiLink.Edge = 0xff; bidiLink.Side = side; Polys[landPolyIdx].Links.Add(bidiLink); } } }
public MeshTile(int x, int y, int layer, PolyIdManager manager, PolyId baseRef) : this(new Vector2i(x, y), layer, manager, baseRef) { }