public Status Init(NavMeshBuilder data, int flags) { if (data.Header.Magic != Helper.NavMeshMagic) { throw new ArgumentException("Wrong Magic Number"); } if (data.Header.Version != Helper.NavMeshVersion) { throw new ArgumentException("Wrong Version Number"); } NavMeshParams param = new NavMeshParams(); Array.Copy(data.Header.BMin, param.Orig, 3); param.TileWidth = data.Header.BMax[0] - data.Header.BMin[0]; param.TileHeight = data.Header.BMax[2] - data.Header.BMin[2]; param.MaxTiles = 1; param.MaxPolys = data.Header.PolyCount; Status status = Init(param); if ((status & Status.Failure) == Status.Failure) { return(status); } long temp = 0; return(AddTile(data, flags, 0, ref temp)); }
public Status RemoveTile(long refId, out NavMeshBuilder data) { data = null; if (refId == 0) { return(Status.Failure | Status.InvalidParam); } long tileIndex = DecodePolyIdTile(refId); long tileSalt = DecodePolyIdSalt(refId); if (tileIndex >= _maxTiles) { return(Status.Failure | Status.InvalidParam); } MeshTile tile = _tiles[tileIndex]; if (tile.Salt != tileSalt) { return(Status.Failure | Status.InvalidParam); } int h = ComputeTileHash(tile.Header.X, tile.Header.Y, _tileLutMask); MeshTile prev = null; MeshTile cur = _posLookup[h]; while (cur != null) { if (cur == tile) { if (prev != null) { prev.Next = cur.Next; } else { _posLookup[h] = cur.Next; } break; } prev = cur; cur = cur.Next; } int MaxNeis = 32; MeshTile[] neis = new MeshTile[MaxNeis]; int nneis; nneis = GetTilesAt(tile.Header.X, tile.Header.Y, ref neis, MaxNeis); for (int j = 0; j < nneis; j++) { if (neis[j] == tile) { continue; } MeshTile temp = neis[j]; UnconnectExtLinks(ref temp, ref tile); } for (int i = 0; i < 8; i++) { nneis = GetNeighborTilesAt(tile.Header.X, tile.Header.Y, i, ref neis, MaxNeis); for (int j = 0; j < nneis; j++) { MeshTile temp = neis[j]; UnconnectExtLinks(ref temp, ref tile); } } // reset tile if ((tile.Flags & TileFreeData) != 0) { tile.Data = null; } else { data = tile.Data; } tile.Header = null; tile.Flags = 0; tile.LinksFreeList = 0; tile.Polys = null; tile.Verts = null; tile.Links = null; tile.DetailMeshes = null; tile.DetailVerts = null; tile.DetailTris = null; tile.BVTree = null; tile.OffMeshCons = null; tile.Salt = (tile.Salt + 1) & ((1 << (int)_saltBits) - 1); if (tile.Salt == 0) { tile.Salt++; } tile.Next = _nextFree; _nextFree = tile; return(Status.Success); }
public Status AddTile(NavMeshBuilder data, int flags, long lastRef, ref long result) { MeshHeader header = data.Header; if (header.Magic != Helper.NavMeshMagic) { return(Status.Failure | Status.WrongMagic); } if (header.Version != Helper.NavMeshVersion) { return(Status.Failure | Status.WrongVersion); } if (GetTileAt(header.X, header.Y, header.Layer) != null) { return(Status.Failure); } MeshTile tile = null; if (lastRef == 0) { if (_nextFree != null) { tile = _nextFree; _nextFree = tile.Next; tile.Next = null; } } else { int tileIndex = (int)DecodePolyIdTile(lastRef); if (tileIndex >= _maxTiles) { return(Status.Failure | Status.OutOfMemory); } MeshTile target = _tiles[tileIndex]; MeshTile prev = null; tile = _nextFree; while (tile != null && tile != target) { prev = tile; tile = tile.Next; } if (tile != target) { return(Status.Failure | Status.OutOfMemory); } if (prev != null) { _nextFree = tile.Next; } else { prev.Next = tile.Next; } tile.Salt = DecodePolyIdSalt(lastRef); } if (tile == null) { return(Status.Failure | Status.OutOfMemory); } // insert tile into the position int h = ComputeTileHash(header.X, header.Y, _tileLutMask); tile.Next = _posLookup[h]; _posLookup[h] = tile; tile.Verts = data.NavVerts; tile.Polys = data.NavPolys; tile.Links = data.NavLinks; tile.DetailMeshes = data.NavDMeshes; tile.DetailVerts = data.NavDVerts; tile.DetailTris = data.NavDTris; tile.BVTree = data.NavBvTree; tile.OffMeshCons = data.OffMeshCons; tile.LinksFreeList = 0; tile.Links[header.MaxLinkCount - 1].Next = NullLink; for (int i = 0; i < header.MaxLinkCount - 1; i++) { tile.Links[i].Next = i + 1; } tile.Data = data; tile.Header = header; tile.Flags = flags; ConnectIntLinks(tile); BaseOffMeshLinks(tile); int MaxNeis = 32; MeshTile[] neis = new MeshTile[MaxNeis]; int nneis; nneis = GetTilesAt(header.X, header.Y, ref neis, MaxNeis); for (int j = 0; j < nneis; j++) { MeshTile temp = neis[j]; if (neis[j] != tile) { ConnectExtLinks(ref tile, ref temp, -1); ConnectExtLinks(ref temp, ref tile, -1); } ConnectExtOffMeshLinks(ref tile, ref temp, -1); ConnectExtOffMeshLinks(ref temp, ref tile, -1); } for (int i = 0; i < 8; i++) { nneis = GetNeighborTilesAt(header.X, header.Y, i, ref neis, MaxNeis); for (int j = 0; j < nneis; j++) { MeshTile temp = neis[j]; ConnectExtLinks(ref tile, ref temp, i); ConnectExtLinks(ref temp, ref tile, Helper.OppositeTile(i)); ConnectExtOffMeshLinks(ref tile, ref temp, i); ConnectExtOffMeshLinks(ref temp, ref tile, Helper.OppositeTile(i)); } } result = GetTileRef(tile); return(Status.Success); }