@par The add operation will fail if the data is in the wrong format, the allocated tile space is full, or there is a tile already at the specified reference. The lastRef parameter is used to restore a tile with the same tile reference it had previously used. In this case the #dtPolyRef's for the tile will be restored to the same values they were before the tile was removed. The nav mesh assume
| 898 | /// |
| 899 | /// @see dtCreateNavMeshData, #removeTile |
| 900 | dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, |
| 901 | dtTileRef lastRef, dtTileRef* result) |
| 902 | { |
| 903 | // Make sure the data is in right format. |
| 904 | dtMeshHeader* header = (dtMeshHeader*)data; |
| 905 | if (header->magic != DT_NAVMESH_MAGIC) |
| 906 | return DT_FAILURE | DT_WRONG_MAGIC; |
| 907 | if (header->version != DT_NAVMESH_VERSION) |
| 908 | return DT_FAILURE | DT_WRONG_VERSION; |
| 909 | |
| 910 | #ifndef DT_POLYREF64 |
| 911 | // Do not allow adding more polygons than specified in the NavMesh's maxPolys constraint. |
| 912 | // Otherwise, the poly ID cannot be represented with the given number of bits. |
| 913 | if (m_polyBits < dtIlog2(dtNextPow2((unsigned int)header->polyCount))) |
| 914 | return DT_FAILURE | DT_INVALID_PARAM; |
| 915 | #endif |
| 916 | |
| 917 | // Make sure the location is free. |
| 918 | if (getTileAt(header->x, header->y, header->layer)) |
| 919 | return DT_FAILURE | DT_ALREADY_OCCUPIED; |
| 920 | |
| 921 | // Allocate a tile. |
| 922 | dtMeshTile* tile = 0; |
| 923 | if (!lastRef) |
| 924 | { |
| 925 | if (m_nextFree) |
| 926 | { |
| 927 | tile = m_nextFree; |
| 928 | m_nextFree = tile->next; |
| 929 | tile->next = 0; |
| 930 | } |
| 931 | } |
| 932 | else |
| 933 | { |
| 934 | // Try to relocate the tile to specific index with same salt. |
| 935 | int tileIndex = (int)decodePolyIdTile((dtPolyRef)lastRef); |
| 936 | if (tileIndex >= m_maxTiles) |
| 937 | return DT_FAILURE | DT_OUT_OF_MEMORY; |
| 938 | // Try to find the specific tile id from the free list. |
| 939 | dtMeshTile* target = &m_tiles[tileIndex]; |
| 940 | dtMeshTile* prev = 0; |
| 941 | tile = m_nextFree; |
| 942 | while (tile && tile != target) |
| 943 | { |
| 944 | prev = tile; |
| 945 | tile = tile->next; |
| 946 | } |
| 947 | // Could not find the correct location. |
| 948 | if (tile != target) |
| 949 | return DT_FAILURE | DT_OUT_OF_MEMORY; |
| 950 | // Remove from freelist |
| 951 | if (!prev) |
| 952 | m_nextFree = tile->next; |
| 953 | else |
| 954 | prev->next = tile->next; |
| 955 | |
| 956 | // Restore salt. |
| 957 | tile->salt = decodePolyIdSalt((dtPolyRef)lastRef); |
no test coverage detected