**API CHANGED** Implemented issue 124. Detour API returns error codes.

This commit is contained in:
Mikko Mononen 2010-10-29 12:08:13 +00:00
parent 30b581b67d
commit e5d603ac92
15 changed files with 1489 additions and 1540 deletions

View File

@ -421,7 +421,7 @@ void duDebugDrawNavMeshPoly(duDebugDraw* dd, const dtNavMesh& mesh, dtPolyRef re
const dtMeshTile* tile = 0; const dtMeshTile* tile = 0;
const dtPoly* poly = 0; const dtPoly* poly = 0;
if (!mesh.getTileAndPolyByRef(ref, &tile, &poly)) if (mesh.getTileAndPolyByRef(ref, &tile, &poly) != DT_SUCCESS)
return; return;
dd->depthMask(false); dd->depthMask(false);

View File

@ -66,6 +66,17 @@ enum dtPolyTypes
DT_POLYTYPE_OFFMESH_CONNECTION = 1, // Off-mesh connections. DT_POLYTYPE_OFFMESH_CONNECTION = 1, // Off-mesh connections.
}; };
enum dtStatus
{
DT_FAILURE = 0, // Operation failed.
DT_FAILURE_DATA_MAGIC,
DT_FAILURE_DATA_VERSION,
DT_FAILURE_OUT_OF_MEMORY,
DT_SUCCESS, // Operation succeed.
DT_IN_PROGRESS, // Operation still in progress.
};
// Structure describing the navigation polygon data. // Structure describing the navigation polygon data.
struct dtPoly struct dtPoly
{ {
@ -177,7 +188,7 @@ public:
// Params: // Params:
// params - (in) navmesh initialization params, see dtNavMeshParams. // params - (in) navmesh initialization params, see dtNavMeshParams.
// Returns: True if succeed, else false. // Returns: True if succeed, else false.
bool init(const dtNavMeshParams* params); dtStatus init(const dtNavMeshParams* params);
// Initializes the nav mesh for single tile use. // Initializes the nav mesh for single tile use.
// Params: // Params:
@ -185,7 +196,7 @@ public:
// dataSize - (in) Data size of the new tile mesh. // dataSize - (in) Data size of the new tile mesh.
// flags - (in) Tile flags, see dtTileFlags. // flags - (in) Tile flags, see dtTileFlags.
// Returns: True if succeed, else false. // Returns: True if succeed, else false.
bool init(unsigned char* data, const int dataSize, const int flags); dtStatus init(unsigned char* data, const int dataSize, const int flags);
// Returns pointer to navmesh initialization params. // Returns pointer to navmesh initialization params.
const dtNavMeshParams* getParams() const; const dtNavMeshParams* getParams() const;
@ -198,17 +209,16 @@ public:
// dataSize - (in) Data size of the new tile mesh. // dataSize - (in) Data size of the new tile mesh.
// flags - (in) Tile flags, see dtTileFlags. // flags - (in) Tile flags, see dtTileFlags.
// lastRef - (in,optional) Last tile ref, the tile will be restored so that // lastRef - (in,optional) Last tile ref, the tile will be restored so that
// the reference (as well as poly references) will be the same. // the reference (as well as poly references) will be the same. Default: 0.
// Returns: Reference to the tile, 0 if failed. // result - (out,optional) tile ref if the tile was succesfully added.
dtTileRef addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef = 0); dtStatus addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef, dtTileRef* result);
// Removes specified tile. // Removes specified tile.
// Params: // Params:
// ref - (in) Reference to the tile to remove. // ref - (in) Reference to the tile to remove.
// data - (out) Data associated with deleted tile. // data - (out) Data associated with deleted tile.
// dataSize - (out) Size of the data associated with deleted tile. // dataSize - (out) Size of the data associated with deleted tile.
// Returns: True if remove suceed, else false. dtStatus removeTile(dtTileRef ref, unsigned char** data, int* dataSize);
bool removeTile(dtTileRef ref, unsigned char** data, int* dataSize);
// Calculates tile location based in input world position. // Calculates tile location based in input world position.
// Params: // Params:
@ -249,8 +259,7 @@ public:
// ref - (in) reference to a polygon. // ref - (in) reference to a polygon.
// tile - (out) pointer to the tile containing the polygon. // tile - (out) pointer to the tile containing the polygon.
// poly - (out) pointer to the polygon. // poly - (out) pointer to the polygon.
// Returns false if poly ref is not valid, true on success. dtStatus getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const;
bool getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const;
// Returns pointer to tile and polygon pointed by the polygon reference. // Returns pointer to tile and polygon pointed by the polygon reference.
// Note: this function does not check if 'ref' s valid, and is thus faster. Use only with valid refs! // Note: this function does not check if 'ref' s valid, and is thus faster. Use only with valid refs!
@ -273,29 +282,29 @@ public:
// startPos[3] - (out) start point of the link. // startPos[3] - (out) start point of the link.
// endPos[3] - (out) end point of the link. // endPos[3] - (out) end point of the link.
// Returns: true if link is found. // Returns: true if link is found.
bool getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const; dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const;
// Sets polygon flags. // Sets polygon flags.
void setPolyFlags(dtPolyRef ref, unsigned short flags); dtStatus setPolyFlags(dtPolyRef ref, unsigned short flags);
// Return polygon flags. // Return polygon flags.
unsigned short getPolyFlags(dtPolyRef ref) const; dtStatus getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const;
// Set polygon type. // Set polygon type.
void setPolyArea(dtPolyRef ref, unsigned char area); dtStatus setPolyArea(dtPolyRef ref, unsigned char area);
// Return polygon area type. // Return polygon area type.
unsigned char getPolyArea(dtPolyRef ref) const; dtStatus getPolyArea(dtPolyRef ref, unsigned char* resultArea) const;
// Returns number of bytes required to store tile state. // Returns number of bytes required to store tile state.
int getTileStateSize(const dtMeshTile* tile) const; int getTileStateSize(const dtMeshTile* tile) const;
// Stores tile state to buffer. // Stores tile state to buffer.
bool storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const; dtStatus storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const;
// Restores tile state. // Restores tile state.
bool restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize); dtStatus restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize);
// Encodes a tile id. // Encodes a tile id.
@ -371,8 +380,8 @@ private:
dtPolyRef findNearestPolyInTile(const dtMeshTile* tile, const float* center, dtPolyRef findNearestPolyInTile(const dtMeshTile* tile, const float* center,
const float* extents, float* nearestPt) const; const float* extents, float* nearestPt) const;
// Returns closest point on polygon. // Returns closest point on polygon.
bool closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip, dtStatus closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip,
const float* pos, float* closest) const; const float* pos, float* closest) const;
dtNavMeshParams m_params; // Current initialization params. TODO: do not store this info twice. dtNavMeshParams m_params; // Current initialization params. TODO: do not store this info twice.
float m_orig[3]; // Origin of the tile (0,0) float m_orig[3]; // Origin of the tile (0,0)

View File

@ -96,13 +96,6 @@ public:
inline void setExcludeFlags(const unsigned short flags) { m_excludeFlags = flags; } inline void setExcludeFlags(const unsigned short flags) { m_excludeFlags = flags; }
}; };
enum dtQueryState
{
DT_QUERY_FAILED = 0, // Path find failed.
DT_QUERY_RUNNING, // Path find running.
DT_QUERY_READY, // Path find results ready.
};
class dtNavMeshQuery class dtNavMeshQuery
{ {
public: public:
@ -114,17 +107,19 @@ public:
// nav - (in) pointer to navigation mesh data. // nav - (in) pointer to navigation mesh data.
// maxNodes - (in) Maximum number of search nodes to use (max 65536). // maxNodes - (in) Maximum number of search nodes to use (max 65536).
// Returns: True if succeed, else false. // Returns: True if succeed, else false.
bool init(const dtNavMesh* nav, const int maxNodes); dtStatus init(const dtNavMesh* nav, const int maxNodes);
// Finds the nearest navigation polygon around the center location. // Finds the nearest navigation polygon around the center location.
// Params: // Params:
// center[3] - (in) The center of the search box. // center[3] - (in) The center of the search box.
// extents[3] - (in) The extents of the search box. // extents[3] - (in) The extents of the search box.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// nearestRef - (out) Reference to the nearest polygon.
// nearestPt[3] - (out, opt) The nearest point on found polygon, null if not needed. // nearestPt[3] - (out, opt) The nearest point on found polygon, null if not needed.
// Returns: Reference identifier for the polygon, or 0 if no polygons found. // Returns: Reference identifier for the polygon, or 0 if no polygons found.
dtPolyRef findNearestPoly(const float* center, const float* extents, dtStatus findNearestPoly(const float* center, const float* extents,
const dtQueryFilter* filter, float* nearestPt) const; const dtQueryFilter* filter,
dtPolyRef* nearestRef, float* nearestPt) const;
// Returns polygons which overlap the query box. // Returns polygons which overlap the query box.
// Params: // Params:
@ -132,10 +127,11 @@ public:
// extents[3] - (in) the extents of the search box. // extents[3] - (in) the extents of the search box.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// polys - (out) array holding the search result. // polys - (out) array holding the search result.
// polyCount - (out) Number of polygons in search result array.
// maxPolys - (in) The max number of polygons the polys array can hold. // maxPolys - (in) The max number of polygons the polys array can hold.
// Returns: Number of polygons in search result array. dtStatus queryPolygons(const float* center, const float* extents,
int queryPolygons(const float* center, const float* extents, const dtQueryFilter* filter, const dtQueryFilter* filter,
dtPolyRef* polys, const int maxPolys) const; dtPolyRef* polys, int* polyCount, const int maxPolys) const;
// Finds path from start polygon to end polygon. // Finds path from start polygon to end polygon.
// If target polygon canno be reached through the navigation graph, // If target polygon canno be reached through the navigation graph,
@ -149,12 +145,12 @@ public:
// endPos[3] - (in) Path end location. // endPos[3] - (in) Path end location.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// path - (out) array holding the search result. // path - (out) array holding the search result.
// maxPathSize - (in) The max number of polygons the path array can hold. Must be at least 1. // pathCount - (out) Number of polygons in search result array.
// Returns: Number of polygons in search result array. // maxPath - (in) The max number of polygons the path array can hold. Must be at least 1.
int findPath(dtPolyRef startRef, dtPolyRef endRef, dtStatus findPath(dtPolyRef startRef, dtPolyRef endRef,
const float* startPos, const float* endPos, const float* startPos, const float* endPos,
const dtQueryFilter* filter, const dtQueryFilter* filter,
dtPolyRef* path, const int maxPathSize) const; dtPolyRef* path, int* pathCount, const int maxPath) const;
// Intializes sliced path find query. // Intializes sliced path find query.
// Note 1: calling any other dtNavMeshQuery method before calling findPathEnd() // Note 1: calling any other dtNavMeshQuery method before calling findPathEnd()
@ -167,22 +163,21 @@ public:
// startPos[3] - (in) Path start location. // startPos[3] - (in) Path start location.
// endPos[3] - (in) Path end location. // endPos[3] - (in) Path end location.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// Returns: Path query state. dtStatus initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef,
dtQueryState initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, const float* startPos, const float* endPos,
const float* startPos, const float* endPos, const dtQueryFilter* filter);
const dtQueryFilter* filter);
// Updates sliced path find query. // Updates sliced path find query.
// Params: // Params:
// maxIter - (in) max number of iterations to update. // maxIter - (in) max number of iterations to update.
// Returns: Path query state. // Returns: Path query state.
dtQueryState updateSlicedFindPath(const int maxIter); dtStatus updateSlicedFindPath(const int maxIter);
// Finalizes sliced path find query. // Finalizes sliced path find query.
// path - (out) array holding the search result. // path - (out) array holding the search result.
// maxPathSize - (in) The max number of polygons the path array can hold. // pathCount - (out) Number of polygons in search result array.
// Returns: Number of polygons in search result array. // maxPath - (in) The max number of polygons the path array can hold.
int finalizeSlicedFindPath(dtPolyRef* path, const int maxPathSize); dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath);
// Finds a straight path from start to end locations within the corridor // Finds a straight path from start to end locations within the corridor
// described by the path polygons. // described by the path polygons.
@ -198,12 +193,12 @@ public:
// straightPath - (out) Points describing the straight path. // straightPath - (out) Points describing the straight path.
// straightPathFlags - (out, opt) Flags describing each point type, see dtStraightPathFlags. // straightPathFlags - (out, opt) Flags describing each point type, see dtStraightPathFlags.
// straightPathRefs - (out, opt) References to polygons at point locations. // straightPathRefs - (out, opt) References to polygons at point locations.
// maxStraightPathSize - (in) The max number of points the straight path array can hold. Must be at least 1. // straightPathCount - (out) Number of points in the path.
// Returns: Number of points in the path. // maxStraightPath - (in) The max number of points the straight path array can hold. Must be at least 1.
int findStraightPath(const float* startPos, const float* endPos, dtStatus findStraightPath(const float* startPos, const float* endPos,
const dtPolyRef* path, const int pathSize, const dtPolyRef* path, const int pathSize,
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
const int maxStraightPathSize) const; int* straightPathCount, const int maxStraightPath) const;
// Moves from startPos to endPos constrained to the navmesh. // Moves from startPos to endPos constrained to the navmesh.
// If the endPos is reachable, the resultPos will be endPos, // If the endPos is reachable, the resultPos will be endPos,
@ -217,11 +212,11 @@ public:
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// resultPos[3] - (out) new position of the mover. // resultPos[3] - (out) new position of the mover.
// visited - (out) array of visited polygons. // visited - (out) array of visited polygons.
// visitedCount - (out) Number of entries in the visited array.
// maxVisitedSize - (in) max number of polygons in the visited array. // maxVisitedSize - (in) max number of polygons in the visited array.
// Returns: Number of entries in the visited array. dtStatus moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos,
int moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos, const dtQueryFilter* filter,
const dtQueryFilter* filter, float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const;
float* resultPos, dtPolyRef* visited, const int maxVisitedSize) const;
// Casts 'walkability' ray along the navmesh surface from startPos towards the endPos. // Casts 'walkability' ray along the navmesh surface from startPos towards the endPos.
// Params: // Params:
@ -231,23 +226,25 @@ public:
// t - (out) hit parameter along the segment, FLT_MAX if no hit. // t - (out) hit parameter along the segment, FLT_MAX if no hit.
// hitNormal[3] - (out) normal of the nearest hit. // hitNormal[3] - (out) normal of the nearest hit.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// path - (out) visited path polygons. // path - (out,opt) visited path polygons.
// pathSize - (in) max number of polygons in the path array. // pathCount - (out,opt) Number of polygons visited.
// Returns: Number of polygons visited or 0 if failed. // maxPath - (in) max number of polygons in the path array.
int raycast(dtPolyRef startRef, const float* startPos, const float* endPos, const dtQueryFilter* filter, dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos,
float& t, float* hitNormal, dtPolyRef* path, const int pathSize) const; const dtQueryFilter* filter,
float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const;
// Returns distance to nearest wall from the specified location. // Returns distance to nearest wall from the specified location.
// Params: // Params:
// centerRef - (in) ref to the polygon where the center lies. // startRef - (in) ref to the polygon where the center lies.
// centerPos[3] - (in) center if the query circle. // centerPos[3] - (in) center if the query circle.
// maxRadius - (in) max search radius. // maxRadius - (in) max search radius.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// hitDist - (out) distance to nearest wall from the test location.
// hitPos[3] - (out) location of the nearest hit. // hitPos[3] - (out) location of the nearest hit.
// hitNormal[3] - (out) normal of the nearest hit. // hitNormal[3] - (out) normal of the nearest hit.
// Returns: Distance to nearest wall from the test location. dtStatus findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius,
float findDistanceToWall(dtPolyRef centerRef, const float* centerPos, float maxRadius, const dtQueryFilter* filter,
const dtQueryFilter* filter, float* hitPos, float* hitNormal) const; float* hitDist, float* hitPos, float* hitNormal) const;
// Finds polygons found along the navigation graph which touch the specified circle. // Finds polygons found along the navigation graph which touch the specified circle.
// Params: // Params:
@ -258,12 +255,12 @@ public:
// resultRef - (out, opt) refs to the polygons touched by the circle. // resultRef - (out, opt) refs to the polygons touched by the circle.
// resultParent - (out, opt) parent of each result polygon. // resultParent - (out, opt) parent of each result polygon.
// resultCost - (out, opt) search cost at each result polygon. // resultCost - (out, opt) search cost at each result polygon.
// resultCount - (out, opt) Number of results.
// maxResult - (int) maximum capacity of search results. // maxResult - (int) maximum capacity of search results.
// Returns: Number of results. dtStatus findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius,
int findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius, const dtQueryFilter* filter,
const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, int* resultCount, const int maxResult) const;
const int maxResult) const;
// Finds polygons found along the navigation graph which touch the convex polygon shape. // Finds polygons found along the navigation graph which touch the convex polygon shape.
// Params: // Params:
@ -274,12 +271,12 @@ public:
// resultRef - (out, opt) refs to the polygons touched by the circle. // resultRef - (out, opt) refs to the polygons touched by the circle.
// resultParent - (out, opt) parent of each result polygon. // resultParent - (out, opt) parent of each result polygon.
// resultCost - (out, opt) search cost at each result polygon. // resultCost - (out, opt) search cost at each result polygon.
// resultCount - (out) number of results.
// maxResult - (int) maximum capacity of search results. // maxResult - (int) maximum capacity of search results.
// Returns: Number of results. dtStatus findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts,
int findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts, const dtQueryFilter* filter,
const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, int* resultCount, const int maxResult) const;
const int maxResult) const;
// Finds non-overlapping local neighbourhood around center location. // Finds non-overlapping local neighbourhood around center location.
// Note: The algorithm is optimized for small query radius and small number of polygons. // Note: The algorithm is optimized for small query radius and small number of polygons.
@ -290,21 +287,22 @@ public:
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// resultRef - (out) refs to the polygons touched by the circle. // resultRef - (out) refs to the polygons touched by the circle.
// resultParent - (out, opt) parent of each result polygon. // resultParent - (out, opt) parent of each result polygon.
// resultCount - (out) number of results.
// maxResult - (int) maximum capacity of search results. // maxResult - (int) maximum capacity of search results.
// Returns: Number of results. dtStatus findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius,
int findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius, const dtQueryFilter* filter,
const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent,
dtPolyRef* resultRef, dtPolyRef* resultParent, const int maxResult) const; int* resultCount, const int maxResult) const;
// Returns wall segments of specified polygon. // Returns wall segments of specified polygon.
// Params: // Params:
// ref - (in) ref to the polygon. // ref - (in) ref to the polygon.
// filter - (in) path polygon filter. // filter - (in) path polygon filter.
// segments[6*maxSegments] - (out) wall segments (2 endpoints per segment). // segments[6*maxSegments] - (out) wall segments (2 endpoints per segment).
// segmentCount - (out) number of wall segments.
// maxSegments - (in) max number of segments that can be stored in 'segments'. // maxSegments - (in) max number of segments that can be stored in 'segments'.
// Returns: Number of wall segments. dtStatus getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter,
int getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, float* segments, int* segmentCount, const int maxSegments) const;
float* segments, const int maxSegments);
// Returns closest point on navigation polygon. // Returns closest point on navigation polygon.
// Uses detail polygons to find the closest point to the navigation polygon surface. // Uses detail polygons to find the closest point to the navigation polygon surface.
@ -313,7 +311,7 @@ public:
// pos[3] - (in) the point to check. // pos[3] - (in) the point to check.
// closest[3] - (out) closest point. // closest[3] - (out) closest point.
// Returns: true if closest point found. // Returns: true if closest point found.
bool closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest) const; dtStatus closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest) const;
// Returns closest point on navigation polygon boundary. // Returns closest point on navigation polygon boundary.
// Uses the navigation polygon boundary to snap the point to poly boundary // Uses the navigation polygon boundary to snap the point to poly boundary
@ -323,7 +321,7 @@ public:
// pos[3] - (in) the point to check. // pos[3] - (in) the point to check.
// closest[3] - (out) closest point. // closest[3] - (out) closest point.
// Returns: true if closest point found. // Returns: true if closest point found.
bool closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const; dtStatus closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const;
// Returns start and end location of an off-mesh link polygon. // Returns start and end location of an off-mesh link polygon.
// Params: // Params:
@ -332,7 +330,7 @@ public:
// startPos[3] - (out) start point of the link. // startPos[3] - (out) start point of the link.
// endPos[3] - (out) end point of the link. // endPos[3] - (out) end point of the link.
// Returns: true if link is found. // Returns: true if link is found.
bool getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const; dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const;
// Returns height of the polygon at specified location. // Returns height of the polygon at specified location.
// Params: // Params:
@ -340,7 +338,7 @@ public:
// pos[3] - (in) the point where to locate the height. // pos[3] - (in) the point where to locate the height.
// height - (out) height at the location. // height - (out) height at the location.
// Returns: true if over polygon. // Returns: true if over polygon.
bool getPolyHeight(dtPolyRef ref, const float* pos, float* height) const; dtStatus getPolyHeight(dtPolyRef ref, const float* pos, float* height) const;
// Returns true if poly reference ins in closed list. // Returns true if poly reference ins in closed list.
bool isInClosedList(dtPolyRef ref) const; bool isInClosedList(dtPolyRef ref) const;
@ -359,26 +357,26 @@ private:
dtPolyRef findNearestPolyInTile(const dtMeshTile* tile, const float* center, const float* extents, dtPolyRef findNearestPolyInTile(const dtMeshTile* tile, const float* center, const float* extents,
const dtQueryFilter* filter, float* nearestPt) const; const dtQueryFilter* filter, float* nearestPt) const;
// Returns closest point on polygon. // Returns closest point on polygon.
bool closestPointOnPolyInTile(const dtMeshTile* tile, const dtPoly* poly, const float* pos, float* closest) const; dtStatus closestPointOnPolyInTile(const dtMeshTile* tile, const dtPoly* poly, const float* pos, float* closest) const;
// Returns portal points between two polygons. // Returns portal points between two polygons.
bool getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right, dtStatus getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right,
unsigned char& fromType, unsigned char& toType) const; unsigned char& fromType, unsigned char& toType) const;
bool getPortalPoints(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile, dtStatus getPortalPoints(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile,
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile, dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
float* left, float* right) const; float* left, float* right) const;
// Returns edge mid point between two polygons. // Returns edge mid point between two polygons.
bool getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const; dtStatus getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const;
bool getEdgeMidPoint(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile, dtStatus getEdgeMidPoint(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile,
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile, dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
float* mid) const; float* mid) const;
const dtNavMesh* m_nav; // Pointer to navmesh data. const dtNavMesh* m_nav; // Pointer to navmesh data.
struct dtQueryData struct dtQueryData
{ {
dtQueryState state; dtStatus status;
struct dtNode* lastBestNode; struct dtNode* lastBestNode;
float lastBestNodeCost; float lastBestNodeCost;
dtPolyRef startRef, endRef; dtPolyRef startRef, endRef;

View File

@ -174,7 +174,7 @@ dtNavMesh::~dtNavMesh()
dtFree(m_tiles); dtFree(m_tiles);
} }
bool dtNavMesh::init(const dtNavMeshParams* params) dtStatus dtNavMesh::init(const dtNavMeshParams* params)
{ {
memcpy(&m_params, params, sizeof(dtNavMeshParams)); memcpy(&m_params, params, sizeof(dtNavMeshParams));
dtVcopy(m_orig, params->orig); dtVcopy(m_orig, params->orig);
@ -189,10 +189,10 @@ bool dtNavMesh::init(const dtNavMeshParams* params)
m_tiles = (dtMeshTile*)dtAlloc(sizeof(dtMeshTile)*m_maxTiles, DT_ALLOC_PERM); m_tiles = (dtMeshTile*)dtAlloc(sizeof(dtMeshTile)*m_maxTiles, DT_ALLOC_PERM);
if (!m_tiles) if (!m_tiles)
return false; return DT_FAILURE;
m_posLookup = (dtMeshTile**)dtAlloc(sizeof(dtMeshTile*)*m_tileLutSize, DT_ALLOC_PERM); m_posLookup = (dtMeshTile**)dtAlloc(sizeof(dtMeshTile*)*m_tileLutSize, DT_ALLOC_PERM);
if (!m_posLookup) if (!m_posLookup)
return false; return DT_FAILURE;
memset(m_tiles, 0, sizeof(dtMeshTile)*m_maxTiles); memset(m_tiles, 0, sizeof(dtMeshTile)*m_maxTiles);
memset(m_posLookup, 0, sizeof(dtMeshTile*)*m_tileLutSize); memset(m_posLookup, 0, sizeof(dtMeshTile*)*m_tileLutSize);
m_nextFree = 0; m_nextFree = 0;
@ -208,19 +208,19 @@ bool dtNavMesh::init(const dtNavMeshParams* params)
m_polyBits = dtIlog2(dtNextPow2((unsigned int)params->maxPolys)); m_polyBits = dtIlog2(dtNextPow2((unsigned int)params->maxPolys));
m_saltBits = 32 - m_tileBits - m_polyBits; m_saltBits = 32 - m_tileBits - m_polyBits;
if (m_saltBits < 10) if (m_saltBits < 10)
return false; return DT_FAILURE;
return true; return DT_SUCCESS;
} }
bool dtNavMesh::init(unsigned char* data, const int dataSize, const int flags) dtStatus dtNavMesh::init(unsigned char* data, const int dataSize, const int flags)
{ {
// Make sure the data is in right format. // Make sure the data is in right format.
dtMeshHeader* header = (dtMeshHeader*)data; dtMeshHeader* header = (dtMeshHeader*)data;
if (header->magic != DT_NAVMESH_MAGIC) if (header->magic != DT_NAVMESH_MAGIC)
return false; return DT_FAILURE;
if (header->version != DT_NAVMESH_VERSION) if (header->version != DT_NAVMESH_VERSION)
return false; return DT_FAILURE;
dtNavMeshParams params; dtNavMeshParams params;
dtVcopy(params.orig, header->bmin); dtVcopy(params.orig, header->bmin);
@ -228,10 +228,12 @@ bool dtNavMesh::init(unsigned char* data, const int dataSize, const int flags)
params.tileHeight = header->bmax[2] - header->bmin[2]; params.tileHeight = header->bmax[2] - header->bmin[2];
params.maxTiles = 1; params.maxTiles = 1;
params.maxPolys = header->polyCount; params.maxPolys = header->polyCount;
if (!init(&params))
return false;
return addTile(data, dataSize, flags) != 0; dtStatus res = init(&params);
if (res != DT_SUCCESS)
return res;
return addTile(data, dataSize, flags, 0, 0);
} }
const dtNavMeshParams* dtNavMesh::getParams() const const dtNavMeshParams* dtNavMesh::getParams() const
@ -553,8 +555,8 @@ void dtNavMesh::connectIntOffMeshLinks(dtMeshTile* tile)
} }
} }
bool dtNavMesh::closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip, dtStatus dtNavMesh::closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip,
const float* pos, float* closest) const const float* pos, float* closest) const
{ {
const dtPoly* poly = &tile->polys[ip]; const dtPoly* poly = &tile->polys[ip];
@ -582,7 +584,7 @@ bool dtNavMesh::closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip
} }
} }
return true; return DT_SUCCESS;
} }
dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile, dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile,
@ -604,7 +606,7 @@ dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile,
{ {
dtPolyRef ref = polys[i]; dtPolyRef ref = polys[i];
float closestPtPoly[3]; float closestPtPoly[3];
if (!closestPointOnPolyInTile(tile, decodePolyIdPoly(ref), center, closestPtPoly)) if (closestPointOnPolyInTile(tile, decodePolyIdPoly(ref), center, closestPtPoly) != DT_SUCCESS)
continue; continue;
float d = dtVdistSqr(center, closestPtPoly); float d = dtVdistSqr(center, closestPtPoly);
if (d < nearestDistanceSqr) if (d < nearestDistanceSqr)
@ -700,18 +702,19 @@ int dtNavMesh::queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, co
} }
} }
dtTileRef dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef) dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags,
dtTileRef lastRef, dtTileRef* result)
{ {
// Make sure the data is in right format. // Make sure the data is in right format.
dtMeshHeader* header = (dtMeshHeader*)data; dtMeshHeader* header = (dtMeshHeader*)data;
if (header->magic != DT_NAVMESH_MAGIC) if (header->magic != DT_NAVMESH_MAGIC)
return 0; return DT_FAILURE_DATA_MAGIC;
if (header->version != DT_NAVMESH_VERSION) if (header->version != DT_NAVMESH_VERSION)
return 0; return DT_FAILURE_DATA_VERSION;
// Make sure the location is free. // Make sure the location is free.
if (getTileAt(header->x, header->y)) if (getTileAt(header->x, header->y))
return 0; return DT_FAILURE;
// Allocate a tile. // Allocate a tile.
dtMeshTile* tile = 0; dtMeshTile* tile = 0;
@ -726,12 +729,10 @@ dtTileRef dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, dtTil
} }
else else
{ {
// TODO: Better error reporting!
// Try to relocate the tile to specific index with same salt. // Try to relocate the tile to specific index with same salt.
int tileIndex = (int)decodePolyIdTile((dtPolyRef)lastRef); int tileIndex = (int)decodePolyIdTile((dtPolyRef)lastRef);
if (tileIndex >= m_maxTiles) if (tileIndex >= m_maxTiles)
return 0; return DT_FAILURE_OUT_OF_MEMORY;
// Try to find the specific tile id from the free list. // Try to find the specific tile id from the free list.
dtMeshTile* target = &m_tiles[tileIndex]; dtMeshTile* target = &m_tiles[tileIndex];
dtMeshTile* prev = 0; dtMeshTile* prev = 0;
@ -743,7 +744,7 @@ dtTileRef dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, dtTil
} }
// Could not find the correct location. // Could not find the correct location.
if (tile != target) if (tile != target)
return 0; return DT_FAILURE_OUT_OF_MEMORY;
// Remove from freelist // Remove from freelist
if (!prev) if (!prev)
m_nextFree = tile->next; m_nextFree = tile->next;
@ -756,7 +757,7 @@ dtTileRef dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, dtTil
// Make sure we could allocate a tile. // Make sure we could allocate a tile.
if (!tile) if (!tile)
return 0; return DT_FAILURE_OUT_OF_MEMORY;
// Insert tile into the position lut. // Insert tile into the position lut.
int h = computeTileHash(header->x, header->y, m_tileLutMask); int h = computeTileHash(header->x, header->y, m_tileLutMask);
@ -812,7 +813,10 @@ dtTileRef dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, dtTil
} }
} }
return getTileRef(tile); if (result)
*result = getTileRef(tile);
return DT_SUCCESS;
} }
const dtMeshTile* dtNavMesh::getTileAt(int x, int y) const const dtMeshTile* dtNavMesh::getTileAt(int x, int y) const
@ -904,26 +908,16 @@ void dtNavMesh::calcTileLoc(const float* pos, int* tx, int* ty) const
*ty = (int)floorf((pos[2]-m_orig[2]) / m_tileHeight); *ty = (int)floorf((pos[2]-m_orig[2]) / m_tileHeight);
} }
/*const dtPoly* dtNavMesh::getPolyByRef(dtPolyRef ref) const dtStatus dtNavMesh::getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
decodePolyId(ref, salt, it, ip); decodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return 0; if (it >= (unsigned int)m_maxTiles) return DT_FAILURE;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE;
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return 0; if (ip >= (unsigned int)m_tiles[it].header->polyCount) return DT_FAILURE;
return &m_tiles[it].polys[ip];
}*/
bool dtNavMesh::getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const
{
unsigned int salt, it, ip;
decodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return false;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return false;
*tile = &m_tiles[it]; *tile = &m_tiles[it];
*poly = &m_tiles[it].polys[ip]; *poly = &m_tiles[it].polys[ip];
return true; return DT_SUCCESS;
} }
void dtNavMesh::getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const void dtNavMesh::getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const
@ -944,17 +938,17 @@ bool dtNavMesh::isValidPolyRef(dtPolyRef ref) const
return true; return true;
} }
bool dtNavMesh::removeTile(dtTileRef ref, unsigned char** data, int* dataSize) dtStatus dtNavMesh::removeTile(dtTileRef ref, unsigned char** data, int* dataSize)
{ {
if (!ref) if (!ref)
return false; return DT_FAILURE;
unsigned int tileIndex = decodePolyIdTile((dtPolyRef)ref); unsigned int tileIndex = decodePolyIdTile((dtPolyRef)ref);
unsigned int tileSalt = decodePolyIdSalt((dtPolyRef)ref); unsigned int tileSalt = decodePolyIdSalt((dtPolyRef)ref);
if ((int)tileIndex >= m_maxTiles) if ((int)tileIndex >= m_maxTiles)
return false; return DT_FAILURE;
dtMeshTile* tile = &m_tiles[tileIndex]; dtMeshTile* tile = &m_tiles[tileIndex];
if (tile->salt != tileSalt) if (tile->salt != tileSalt)
return false; return DT_FAILURE;
// Remove tile from hash lookup. // Remove tile from hash lookup.
int h = computeTileHash(tile->header->x,tile->header->y,m_tileLutMask); int h = computeTileHash(tile->header->x,tile->header->y,m_tileLutMask);
@ -1020,7 +1014,7 @@ bool dtNavMesh::removeTile(dtTileRef ref, unsigned char** data, int* dataSize)
tile->next = m_nextFree; tile->next = m_nextFree;
m_nextFree = tile; m_nextFree = tile;
return true; return DT_SUCCESS;
} }
dtTileRef dtNavMesh::getTileRef(const dtMeshTile* tile) const dtTileRef dtNavMesh::getTileRef(const dtMeshTile* tile) const
@ -1058,12 +1052,12 @@ int dtNavMesh::getTileStateSize(const dtMeshTile* tile) const
return headerSize + polyStateSize; return headerSize + polyStateSize;
} }
bool dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const dtStatus dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const
{ {
// Make sure there is enough space to store the state. // Make sure there is enough space to store the state.
const int sizeReq = getTileStateSize(tile); const int sizeReq = getTileStateSize(tile);
if (maxDataSize < sizeReq) if (maxDataSize < sizeReq)
return false; return DT_FAILURE;
dtTileState* tileState = (dtTileState*)data; data += dtAlign4(sizeof(dtTileState)); dtTileState* tileState = (dtTileState*)data; data += dtAlign4(sizeof(dtTileState));
dtPolyState* polyStates = (dtPolyState*)data; data += dtAlign4(sizeof(dtPolyState) * tile->header->polyCount); dtPolyState* polyStates = (dtPolyState*)data; data += dtAlign4(sizeof(dtPolyState) * tile->header->polyCount);
@ -1082,26 +1076,26 @@ bool dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data, cons
s->area = p->getArea(); s->area = p->getArea();
} }
return true; return DT_SUCCESS;
} }
bool dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize) dtStatus dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize)
{ {
// Make sure there is enough space to store the state. // Make sure there is enough space to store the state.
const int sizeReq = getTileStateSize(tile); const int sizeReq = getTileStateSize(tile);
if (maxDataSize < sizeReq) if (maxDataSize < sizeReq)
return false; return DT_FAILURE;
const dtTileState* tileState = (const dtTileState*)data; data += dtAlign4(sizeof(dtTileState)); const dtTileState* tileState = (const dtTileState*)data; data += dtAlign4(sizeof(dtTileState));
const dtPolyState* polyStates = (const dtPolyState*)data; data += dtAlign4(sizeof(dtPolyState) * tile->header->polyCount); const dtPolyState* polyStates = (const dtPolyState*)data; data += dtAlign4(sizeof(dtPolyState) * tile->header->polyCount);
// Check that the restore is possible. // Check that the restore is possible.
if (tileState->magic != DT_NAVMESH_STATE_MAGIC) if (tileState->magic != DT_NAVMESH_STATE_MAGIC)
return false; return DT_FAILURE_DATA_MAGIC;
if (tileState->version != DT_NAVMESH_STATE_VERSION) if (tileState->version != DT_NAVMESH_STATE_VERSION)
return false; return DT_FAILURE_DATA_VERSION;
if (tileState->ref != getTileRef(tile)) if (tileState->ref != getTileRef(tile))
return false; return DT_FAILURE;
// Restore per poly state. // Restore per poly state.
for (int i = 0; i < tile->header->polyCount; ++i) for (int i = 0; i < tile->header->polyCount; ++i)
@ -1112,25 +1106,25 @@ bool dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data, co
p->setArea(s->area); p->setArea(s->area);
} }
return true; return DT_SUCCESS;
} }
// Returns start and end location of an off-mesh link polygon. // Returns start and end location of an off-mesh link polygon.
bool dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const dtStatus dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
// Get current polygon // Get current polygon
decodePolyId(polyRef, salt, it, ip); decodePolyId(polyRef, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return false; if (it >= (unsigned int)m_maxTiles) return DT_FAILURE;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE;
const dtMeshTile* tile = &m_tiles[it]; const dtMeshTile* tile = &m_tiles[it];
if (ip >= (unsigned int)tile->header->polyCount) return false; if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE;
const dtPoly* poly = &tile->polys[ip]; const dtPoly* poly = &tile->polys[ip];
// Make sure that the current poly is indeed off-mesh link. // Make sure that the current poly is indeed off-mesh link.
if (poly->getType() != DT_POLYTYPE_OFFMESH_CONNECTION) if (poly->getType() != DT_POLYTYPE_OFFMESH_CONNECTION)
return false; return DT_FAILURE;
// Figure out which way to hand out the vertices. // Figure out which way to hand out the vertices.
int idx0 = 0, idx1 = 1; int idx0 = 0, idx1 = 1;
@ -1152,57 +1146,69 @@ bool dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef p
dtVcopy(startPos, &tile->verts[poly->verts[idx0]*3]); dtVcopy(startPos, &tile->verts[poly->verts[idx0]*3]);
dtVcopy(endPos, &tile->verts[poly->verts[idx1]*3]); dtVcopy(endPos, &tile->verts[poly->verts[idx1]*3]);
return true; return DT_SUCCESS;
} }
void dtNavMesh::setPolyFlags(dtPolyRef ref, unsigned short flags) dtStatus dtNavMesh::setPolyFlags(dtPolyRef ref, unsigned short flags)
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
decodePolyId(ref, salt, it, ip); decodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return; if (it >= (unsigned int)m_maxTiles) return DT_FAILURE;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE;
dtMeshTile* tile = &m_tiles[it]; dtMeshTile* tile = &m_tiles[it];
if (ip >= (unsigned int)tile->header->polyCount) return; if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE;
dtPoly* poly = &tile->polys[ip]; dtPoly* poly = &tile->polys[ip];
// Change flags. // Change flags.
poly->flags = flags; poly->flags = flags;
return DT_SUCCESS;
} }
unsigned short dtNavMesh::getPolyFlags(dtPolyRef ref) const dtStatus dtNavMesh::getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
decodePolyId(ref, salt, it, ip); decodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return 0; if (it >= (unsigned int)m_maxTiles) return DT_FAILURE;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE;
const dtMeshTile* tile = &m_tiles[it]; const dtMeshTile* tile = &m_tiles[it];
if (ip >= (unsigned int)tile->header->polyCount) return 0; if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE;
const dtPoly* poly = &tile->polys[ip]; const dtPoly* poly = &tile->polys[ip];
return poly->flags;
*resultFlags = poly->flags;
return DT_SUCCESS;
} }
void dtNavMesh::setPolyArea(dtPolyRef ref, unsigned char area) dtStatus dtNavMesh::setPolyArea(dtPolyRef ref, unsigned char area)
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
decodePolyId(ref, salt, it, ip); decodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return; if (it >= (unsigned int)m_maxTiles) return DT_FAILURE;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE;
dtMeshTile* tile = &m_tiles[it]; dtMeshTile* tile = &m_tiles[it];
if (ip >= (unsigned int)tile->header->polyCount) return; if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE;
dtPoly* poly = &tile->polys[ip]; dtPoly* poly = &tile->polys[ip];
poly->setArea(area); poly->setArea(area);
return DT_SUCCESS;
} }
unsigned char dtNavMesh::getPolyArea(dtPolyRef ref) const dtStatus dtNavMesh::getPolyArea(dtPolyRef ref, unsigned char* resultArea) const
{ {
unsigned int salt, it, ip; unsigned int salt, it, ip;
decodePolyId(ref, salt, it, ip); decodePolyId(ref, salt, it, ip);
if (it >= (unsigned int)m_maxTiles) return 0; if (it >= (unsigned int)m_maxTiles) return DT_FAILURE;
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return DT_FAILURE;
const dtMeshTile* tile = &m_tiles[it]; const dtMeshTile* tile = &m_tiles[it];
if (ip >= (unsigned int)tile->header->polyCount) return 0; if (ip >= (unsigned int)tile->header->polyCount) return DT_FAILURE;
const dtPoly* poly = &tile->polys[ip]; const dtPoly* poly = &tile->polys[ip];
return poly->getArea();
*resultArea = poly->getArea();
return DT_SUCCESS;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -284,14 +284,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>52</integer> <integer>59</integer>
<integer>51</integer> <integer>51</integer>
<integer>1</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
</array> </array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 824}, {264, 660}}</string> <string>{{0, 590}, {264, 660}}</string>
</dict> </dict>
<key>PBXTopSmartGroupGIDs</key> <key>PBXTopSmartGroupGIDs</key>
<array/> <array/>
@ -326,7 +326,7 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>CrowdTool.cpp</string> <string>NavMeshTesterTool.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
<dict> <dict>
<key>Split0</key> <key>Split0</key>
@ -334,105 +334,29 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string> <string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>CrowdTool.cpp</string> <string>NavMeshTesterTool.cpp</string>
<key>_historyCapacity</key> <key>_historyCapacity</key>
<integer>0</integer> <integer>0</integer>
<key>bookmark</key> <key>bookmark</key>
<string>6B8D5605127ABBD80077C699</string> <string>6B8D56DA127AEC580077C699</string>
<key>history</key> <key>history</key>
<array> <array>
<string>6BBB4C34115B7A3D00CF791D</string> <string>6B8D565F127ADB0D0077C699</string>
<string>6BF5F27311747CFA000502A6</string> <string>6B8D566D127ADB7D0077C699</string>
<string>6BF5F2E411748884000502A6</string> <string>6B8D566F127ADB7D0077C699</string>
<string>6BF5F2E511748884000502A6</string> <string>6B8D56C7127AEC100077C699</string>
<string>6BF5F2E611748884000502A6</string> <string>6B8D56C8127AEC100077C699</string>
<string>6BF5F2E711748884000502A6</string> <string>6B8D56C9127AEC100077C699</string>
<string>6B98462E11E6141900FA177B</string> <string>6B8D56CA127AEC100077C699</string>
<string>6B98473011E737D800FA177B</string> <string>6B8D56CB127AEC100077C699</string>
<string>6BAF4321121AF998008CFCDF</string> <string>6B8D56CC127AEC100077C699</string>
<string>6BAF4421121C25E3008CFCDF</string> <string>6B8D56CD127AEC100077C699</string>
<string>6BAF4525121D1723008CFCDF</string> <string>6B8D56CE127AEC100077C699</string>
<string>6BAF46D3121D8FF1008CFCDF</string> <string>6B8D56CF127AEC100077C699</string>
<string>6B1C8E08121EB4FF0048697F</string> <string>6B8D56D0127AEC100077C699</string>
<string>6BA6876E1222F02E00730711</string> <string>6B8D56D2127AEC100077C699</string>
<string>6BA687881222F4DB00730711</string> <string>6B8D56D8127AEC580077C699</string>
<string>6BA687CA1222FA9300730711</string> <string>6B8D56D9127AEC580077C699</string>
<string>6BD402111224336600995864</string>
<string>6BD402121224336600995864</string>
<string>6BD402611224387200995864</string>
<string>6BD402621224387200995864</string>
<string>6BD402811224393000995864</string>
<string>6BD4028C1224399300995864</string>
<string>6BD4029B12243A8000995864</string>
<string>6B920A521225C0AC00D5B5AD</string>
<string>6B920A6D1225C5DD00D5B5AD</string>
<string>6BA7F8EC1227002300C8C47A</string>
<string>6B847779122D223D00ADF63D</string>
<string>6B84778B122D279700ADF63D</string>
<string>6B8477BB122D297200ADF63D</string>
<string>6B8477E1122D2B9100ADF63D</string>
<string>6B8477FE122D2E2A00ADF63D</string>
<string>6B8477FF122D2E2A00ADF63D</string>
<string>6BD6681812434B790021A7A4</string>
<string>6BD66855124350F80021A7A4</string>
<string>6BD668A3124361EB0021A7A4</string>
<string>6BD66930124374D60021A7A4</string>
<string>6BD66937124376780021A7A4</string>
<string>6BD66938124376780021A7A4</string>
<string>6BD669501243778E0021A7A4</string>
<string>6BD669511243778E0021A7A4</string>
<string>6BD6695C124377D40021A7A4</string>
<string>6BBB0361124E242E00533229</string>
<string>6BBB0363124E242E00533229</string>
<string>6BA8CECB1255C1A400272A3B</string>
<string>6BA8CECD1255C1A400272A3B</string>
<string>6BA8CEEF1255C4B700272A3B</string>
<string>6BA8CF4A1255D44700272A3B</string>
<string>6BA8CF4D1255D44700272A3B</string>
<string>6BA8CF511255D44700272A3B</string>
<string>6BA8CF5B1255D49B00272A3B</string>
<string>6BA8CF951255D97400272A3B</string>
<string>6BA8CFBE1255DE0500272A3B</string>
<string>6BB2EDF91261C75400E350F8</string>
<string>6BB2EE241261C92300E350F8</string>
<string>6BB2EE261261C92300E350F8</string>
<string>6BB2EE271261C92300E350F8</string>
<string>6BB2EE361261CEB800E350F8</string>
<string>6BB2EE3F1261D02000E350F8</string>
<string>6BB2EE661261D48100E350F8</string>
<string>6BB2EE691261D48100E350F8</string>
<string>6BB2EE731261DA0400E350F8</string>
<string>6B1633101268326F0083FC15</string>
<string>6B1633121268326F0083FC15</string>
<string>6B1633141268326F0083FC15</string>
<string>6B163317126832D20083FC15</string>
<string>6B16357012687A5D0083FC15</string>
<string>6B16358E12687D740083FC15</string>
<string>6B16359012687D740083FC15</string>
<string>6B16359112687D740083FC15</string>
<string>6B1635B9126884520083FC15</string>
<string>6B1635BB126884520083FC15</string>
<string>6B1635C8126885AD0083FC15</string>
<string>6B1635D3126887C80083FC15</string>
<string>6B1635D4126887C80083FC15</string>
<string>6B1635E812688D1B0083FC15</string>
<string>6B16360A126891A40083FC15</string>
<string>6BB9C228126F4A9100B97C1C</string>
<string>6BB9C229126F4A9100B97C1C</string>
<string>6BB9C253126F555F00B97C1C</string>
<string>6BB9C2A2126F623D00B97C1C</string>
<string>6BB9C2AA126F62C000B97C1C</string>
<string>6BB9C2B5127449CE00B97C1C</string>
<string>6BB9C2BD127449CE00B97C1C</string>
<string>6BB9C372127A0E5600B97C1C</string>
<string>6B8D5565127A98FB0077C699</string>
<string>6B8D559F127AA3E70077C699</string>
<string>6B8D55A0127AA3E70077C699</string>
<string>6B8D55B5127AA5E60077C699</string>
<string>6B8D55F2127ABAD40077C699</string>
<string>6B8D55F3127ABAD40077C699</string>
<string>6B8D5603127ABBD80077C699</string>
<string>6B8D5604127ABBD80077C699</string>
</array> </array>
</dict> </dict>
<key>SplitCount</key> <key>SplitCount</key>
@ -446,18 +370,18 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {992, 471}}</string> <string>{{0, 0}, {992, 434}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>0 59 1278 719 0 0 1280 778 </string> <string>0 59 1278 719 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXNavigatorGroup</string> <string>PBXNavigatorGroup</string>
<key>Proportion</key> <key>Proportion</key>
<string>471pt</string> <string>434pt</string>
</dict> </dict>
<dict> <dict>
<key>Proportion</key> <key>Proportion</key>
<string>202pt</string> <string>239pt</string>
<key>Tabs</key> <key>Tabs</key>
<array> <array>
<dict> <dict>
@ -487,7 +411,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {614, 336}}</string> <string>{{10, 27}, {992, 212}}</string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXProjectFindModule</string> <string>PBXProjectFindModule</string>
@ -525,7 +449,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {992, 175}}</string> <string>{{10, 27}, {992, 212}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>0 59 1278 719 0 0 1280 778 </string> <string>0 59 1278 719 0 0 1280 778 </string>
</dict> </dict>
@ -555,11 +479,11 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6B8D5569127A98FB0077C699</string> <string>6B8D5625127AD44A0077C699</string>
<string>1CA23ED40692098700951B8B</string> <string>1CA23ED40692098700951B8B</string>
<string>6B8D556A127A98FB0077C699</string> <string>6B8D5626127AD44A0077C699</string>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<string>6B8D556B127A98FB0077C699</string> <string>6B8D5627127AD44A0077C699</string>
<string>1CA23EDF0692099D00951B8B</string> <string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string> <string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string> <string>1CA23EE10692099D00951B8B</string>
@ -707,14 +631,14 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6B8D5585127AA2270077C699</string> <string>6B8D563A127AD6CA0077C699</string>
<string>1CCC7628064C1048000F2A68</string> <string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string> <string>1CCC7629064C1048000F2A68</string>
<string>6B8D5586127AA2270077C699</string> <string>6B8D563B127AD6CA0077C699</string>
<string>6B8D5587127AA2270077C699</string> <string>6B8D563C127AD6CA0077C699</string>
<string>6B8D5588127AA2270077C699</string> <string>6B8D563D127AD6CA0077C699</string>
<string>6B8D5589127AA2270077C699</string> <string>6B8D563E127AD6CA0077C699</string>
<string>6B8D558A127AA2270077C699</string> <string>6B8D563F127AD6CA0077C699</string>
</array> </array>
<key>ToolbarConfigUserDefaultsMinorVersion</key> <key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string> <string>2</string>
@ -746,9 +670,9 @@
<integer>5</integer> <integer>5</integer>
<key>WindowOrderList</key> <key>WindowOrderList</key>
<array> <array>
<string>6B8D5606127ABBD80077C699</string> <string>6B8D56D5127AEC100077C699</string>
<string>6B8D558C127AA2270077C699</string> <string>6B8D56D6127AEC100077C699</string>
<string>6B8D558D127AA2270077C699</string> <string>6B8D56D7127AEC100077C699</string>
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string> <string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
</array> </array>
<key>WindowString</key> <key>WindowString</key>

View File

@ -32,7 +32,7 @@ class NavMeshTesterTool : public SampleTool
dtQueryFilter m_filter; dtQueryFilter m_filter;
dtQueryState m_pathFindState; dtStatus m_pathFindStatus;
enum ToolMode enum ToolMode
{ {

View File

@ -216,8 +216,8 @@ void PathQueue::update(dtNavMeshQuery* navquery)
PathQuery& q = m_queue[i]; PathQuery& q = m_queue[i];
if (q.ref == PATHQ_INVALID) if (q.ref == PATHQ_INVALID)
continue; continue;
q.npath = navquery->findPath(q.startRef, q.endRef, q.startPos, q.endPos, navquery->findPath(q.startRef, q.endRef, q.startPos, q.endPos,
q.filter, q.path, PQ_MAX_PATH); q.filter, q.path, &q.npath, PQ_MAX_PATH);
q.ready = true; q.ready = true;
break; break;
} }
@ -474,8 +474,9 @@ int PathCorridor::findCorners(float* cornerVerts, unsigned char* cornerFlags,
static const float MIN_TARGET_DIST = 0.01f; static const float MIN_TARGET_DIST = 0.01f;
int ncorners = navquery->findStraightPath(m_pos, m_target, m_path, m_npath, int ncorners = 0;
cornerVerts, cornerFlags, cornerPolys, maxCorners); navquery->findStraightPath(m_pos, m_target, m_path, m_npath,
cornerVerts, cornerFlags, cornerPolys, &ncorners, maxCorners);
// Prune points in the beginning of the path which are too close. // Prune points in the beginning of the path which are too close.
while (ncorners) while (ncorners)
@ -530,7 +531,8 @@ void PathCorridor::optimizePath(const float* next, const float pathOptimizationR
static const int MAX_RES = 32; static const int MAX_RES = 32;
dtPolyRef res[MAX_RES]; dtPolyRef res[MAX_RES];
float t, norm[3]; float t, norm[3];
const int nres = navquery->raycast(m_path[0], m_pos, goal, filter, t, norm, res, MAX_RES); int nres = 0;
navquery->raycast(m_path[0], m_pos, goal, filter, &t, norm, res, &nres, MAX_RES);
if (nres > 1 && t > 0.99f) if (nres > 1 && t > 0.99f)
{ {
m_npath = mergeCorridor(m_path, m_npath, m_maxPath, res, nres); m_npath = mergeCorridor(m_path, m_npath, m_maxPath, res, nres);
@ -546,8 +548,9 @@ void PathCorridor::movePosition(const float* npos, dtNavMeshQuery* navquery, con
float result[3]; float result[3];
static const int MAX_VISITED = 16; static const int MAX_VISITED = 16;
dtPolyRef visited[MAX_VISITED]; dtPolyRef visited[MAX_VISITED];
int nvisited = navquery->moveAlongSurface(m_path[0], m_pos, npos, filter, int nvisited = 0;
result, visited, MAX_VISITED); navquery->moveAlongSurface(m_path[0], m_pos, npos, filter,
result, visited, &nvisited, MAX_VISITED);
m_npath = fixupCorridor(m_path, m_npath, m_maxPath, visited, nvisited); m_npath = fixupCorridor(m_path, m_npath, m_maxPath, visited, nvisited);
// Adjust the position to stay on top of the navmesh. // Adjust the position to stay on top of the navmesh.
@ -566,8 +569,9 @@ void PathCorridor::moveTargetPosition(const float* npos, dtNavMeshQuery* navquer
float result[3]; float result[3];
static const int MAX_VISITED = 16; static const int MAX_VISITED = 16;
dtPolyRef visited[MAX_VISITED]; dtPolyRef visited[MAX_VISITED];
int nvisited = navquery->moveAlongSurface(m_path[m_npath-1], m_target, npos, filter, int nvisited = 0;
result, visited, MAX_VISITED); navquery->moveAlongSurface(m_path[m_npath-1], m_target, npos, filter,
result, visited, &nvisited, MAX_VISITED);
m_npath = fixupCorridorEnd(m_path, m_npath, m_maxPath, visited, nvisited); m_npath = fixupCorridorEnd(m_path, m_npath, m_maxPath, visited, nvisited);
// TODO: should we do that? // TODO: should we do that?
@ -741,15 +745,17 @@ void LocalBoundary::update(dtPolyRef ref, const float* pos, const float collisio
// First query non-overlapping polygons. // First query non-overlapping polygons.
dtPolyRef locals[MAX_LOCAL_POLYS]; dtPolyRef locals[MAX_LOCAL_POLYS];
const int nlocals = navquery->findLocalNeighbourhood(ref, pos, collisionQueryRange, int nlocals = 0;
filter, locals, 0, MAX_LOCAL_POLYS); navquery->findLocalNeighbourhood(ref, pos, collisionQueryRange,
filter, locals, 0, &nlocals, MAX_LOCAL_POLYS);
// Secondly, store all polygon edges. // Secondly, store all polygon edges.
m_nsegs = 0; m_nsegs = 0;
float segs[MAX_SEGS_PER_POLY*6]; float segs[MAX_SEGS_PER_POLY*6];
int nsegs = 0;
for (int j = 0; j < nlocals; ++j) for (int j = 0; j < nlocals; ++j)
{ {
const int nsegs = navquery->getPolyWallSegments(locals[j], filter, segs, MAX_SEGS_PER_POLY); navquery->getPolyWallSegments(locals[j], filter, segs, &nsegs, MAX_SEGS_PER_POLY);
for (int k = 0; k < nsegs; ++k) for (int k = 0; k < nsegs; ++k)
{ {
const float* s = &segs[k*6]; const float* s = &segs[k*6];
@ -855,7 +861,8 @@ int CrowdManager::addAgent(const float* pos, const float radius, const float hei
// Find nearest position on navmesh and place the agent there. // Find nearest position on navmesh and place the agent there.
float nearest[3]; float nearest[3];
dtPolyRef ref = navquery->findNearestPoly(pos, m_ext, &m_filter, nearest); dtPolyRef ref;
navquery->findNearestPoly(pos, m_ext, &m_filter, &ref, nearest);
if (!ref) if (!ref)
{ {
// Could not find a location on navmesh. // Could not find a location on navmesh.
@ -1082,8 +1089,9 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery, c
float result[3]; float result[3];
static const int MAX_VISITED = 16; static const int MAX_VISITED = 16;
dtPolyRef visited[MAX_VISITED]; dtPolyRef visited[MAX_VISITED];
int nvisited = navquery->moveAlongSurface(req->temp[req->ntemp-1], req->pos, req->apos, filter, int nvisited = 0;
result, visited, MAX_VISITED); navquery->moveAlongSurface(req->temp[req->ntemp-1], req->pos, req->apos, filter,
result, visited, &nvisited, MAX_VISITED);
req->ntemp = fixupCorridorEnd(req->temp, req->ntemp, MAX_TEMP_PATH, visited, nvisited); req->ntemp = fixupCorridorEnd(req->temp, req->ntemp, MAX_TEMP_PATH, visited, nvisited);
dtVcopy(req->pos, result); dtVcopy(req->pos, result);
@ -1191,7 +1199,7 @@ void CrowdManager::updateMoveRequest(const float dt, dtNavMeshQuery* navquery, c
{ {
// Partial path, constrain target position inside the last polygon. // Partial path, constrain target position inside the last polygon.
float nearest[3]; float nearest[3];
if (navquery->closestPointOnPoly(res[nres-1], targetPos, nearest)) if (navquery->closestPointOnPoly(res[nres-1], targetPos, nearest) == DT_SUCCESS)
dtVcopy(targetPos, nearest); dtVcopy(targetPos, nearest);
else else
valid = false; valid = false;

View File

@ -253,7 +253,8 @@ void CrowdTool::handleClick(const float* s, const float* p, bool shift)
dtNavMeshQuery* navquery = m_sample->getNavMeshQuery(); dtNavMeshQuery* navquery = m_sample->getNavMeshQuery();
const dtQueryFilter* filter = m_crowd.getFilter(); const dtQueryFilter* filter = m_crowd.getFilter();
const float* ext = m_crowd.getQueryExtents(); const float* ext = m_crowd.getQueryExtents();
m_targetRef = navquery->findNearestPoly(p, ext, filter, m_targetPos);
navquery->findNearestPoly(p, ext, filter, &m_targetRef, m_targetPos);
if (shift) if (shift)
{ {

View File

@ -104,8 +104,9 @@ static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, cons
float steerPath[MAX_STEER_POINTS*3]; float steerPath[MAX_STEER_POINTS*3];
unsigned char steerPathFlags[MAX_STEER_POINTS]; unsigned char steerPathFlags[MAX_STEER_POINTS];
dtPolyRef steerPathPolys[MAX_STEER_POINTS]; dtPolyRef steerPathPolys[MAX_STEER_POINTS];
int nsteerPath = navQuery->findStraightPath(startPos, endPos, path, pathSize, int nsteerPath = 0;
steerPath, steerPathFlags, steerPathPolys, MAX_STEER_POINTS); navQuery->findStraightPath(startPos, endPos, path, pathSize,
steerPath, steerPathFlags, steerPathPolys, &nsteerPath, MAX_STEER_POINTS);
if (!nsteerPath) if (!nsteerPath)
return false; return false;
@ -144,7 +145,7 @@ NavMeshTesterTool::NavMeshTesterTool() :
m_sample(0), m_sample(0),
m_navMesh(0), m_navMesh(0),
m_navQuery(0), m_navQuery(0),
m_pathFindState(DT_QUERY_FAILED), m_pathFindStatus(DT_FAILURE),
m_toolMode(TOOLMODE_PATHFIND_FOLLOW), m_toolMode(TOOLMODE_PATHFIND_FOLLOW),
m_startRef(0), m_startRef(0),
m_endRef(0), m_endRef(0),
@ -234,7 +235,7 @@ void NavMeshTesterTool::handleMenu()
m_toolMode = TOOLMODE_FIND_POLYS_IN_CIRCLE; m_toolMode = TOOLMODE_FIND_POLYS_IN_CIRCLE;
recalc(); recalc();
} }
if (imguiCheck("Find Polys in Poly", m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE)) if (imguiCheck("Find Polys in Shape", m_toolMode == TOOLMODE_FIND_POLYS_IN_SHAPE))
{ {
m_toolMode = TOOLMODE_FIND_POLYS_IN_SHAPE; m_toolMode = TOOLMODE_FIND_POLYS_IN_SHAPE;
recalc(); recalc();
@ -333,7 +334,7 @@ void NavMeshTesterTool::handleStep()
if (m_pathIterNum == 0) if (m_pathIterNum == 0)
{ {
m_npolys = m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS); m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, &m_npolys, MAX_POLYS);
m_nsmoothPath = 0; m_nsmoothPath = 0;
m_pathIterPolyCount = m_npolys; m_pathIterPolyCount = m_npolys;
@ -397,8 +398,9 @@ void NavMeshTesterTool::handleStep()
// Move // Move
float result[3]; float result[3];
dtPolyRef visited[16]; dtPolyRef visited[16];
int nvisited = m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter, int nvisited = 0;
result, visited, 16); m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter,
result, visited, &nvisited, 16);
m_pathIterPolyCount = fixupCorridor(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited); m_pathIterPolyCount = fixupCorridor(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited);
float h = 0; float h = 0;
m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h); m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h);
@ -436,7 +438,7 @@ void NavMeshTesterTool::handleStep()
m_pathIterPolyCount -= npos; m_pathIterPolyCount -= npos;
// Handle the connection. // Handle the connection.
if (m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) if (m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos) == DT_SUCCESS)
{ {
if (m_nsmoothPath < MAX_SMOOTH) if (m_nsmoothPath < MAX_SMOOTH)
{ {
@ -470,14 +472,14 @@ void NavMeshTesterTool::handleUpdate(const float /*dt*/)
{ {
if (m_toolMode == TOOLMODE_PATHFIND_SLICED) if (m_toolMode == TOOLMODE_PATHFIND_SLICED)
{ {
if (m_pathFindState == DT_QUERY_RUNNING) if (m_pathFindStatus == DT_IN_PROGRESS)
{ {
m_pathFindState = m_navQuery->updateSlicedFindPath(1); m_pathFindStatus = m_navQuery->updateSlicedFindPath(1);
} }
if (m_pathFindState == DT_QUERY_READY) if (m_pathFindStatus == DT_SUCCESS)
{ {
m_npolys = m_navQuery->finalizeSlicedFindPath(m_polys, MAX_POLYS); m_navQuery->finalizeSlicedFindPath(m_polys, &m_npolys, MAX_POLYS);
m_nstraightPath = 0; m_nstraightPath = 0;
if (m_npolys) if (m_npolys)
{ {
@ -487,12 +489,12 @@ void NavMeshTesterTool::handleUpdate(const float /*dt*/)
if (m_polys[m_npolys-1] != m_endRef) if (m_polys[m_npolys-1] != m_endRef)
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos); m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos);
m_nstraightPath = m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys, m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
m_straightPath, m_straightPathFlags, m_straightPath, m_straightPathFlags,
m_straightPathPolys, MAX_POLYS); m_straightPathPolys, &m_nstraightPath, MAX_POLYS);
} }
m_pathFindState = DT_QUERY_FAILED; m_pathFindStatus = DT_FAILURE;
} }
} }
} }
@ -516,16 +518,16 @@ void NavMeshTesterTool::recalc()
return; return;
if (m_sposSet) if (m_sposSet)
m_startRef = m_navQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, 0); m_navQuery->findNearestPoly(m_spos, m_polyPickExt, &m_filter, &m_startRef, 0);
else else
m_startRef = 0; m_startRef = 0;
if (m_eposSet) if (m_eposSet)
m_endRef = m_navQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, 0); m_navQuery->findNearestPoly(m_epos, m_polyPickExt, &m_filter, &m_endRef, 0);
else else
m_endRef = 0; m_endRef = 0;
m_pathFindState = DT_QUERY_FAILED; m_pathFindStatus = DT_FAILURE;
if (m_toolMode == TOOLMODE_PATHFIND_FOLLOW) if (m_toolMode == TOOLMODE_PATHFIND_FOLLOW)
{ {
@ -538,7 +540,7 @@ void NavMeshTesterTool::recalc()
m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif #endif
m_npolys = m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS); m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, &m_npolys, MAX_POLYS);
m_nsmoothPath = 0; m_nsmoothPath = 0;
@ -592,9 +594,9 @@ void NavMeshTesterTool::recalc()
// Move // Move
float result[3]; float result[3];
dtPolyRef visited[16]; dtPolyRef visited[16];
int nvisited = 0;
int nvisited = m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter, m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter,
result, visited, 16); result, visited, &nvisited, 16);
npolys = fixupCorridor(polys, npolys, MAX_POLYS, visited, nvisited); npolys = fixupCorridor(polys, npolys, MAX_POLYS, visited, nvisited);
float h = 0; float h = 0;
@ -633,7 +635,7 @@ void NavMeshTesterTool::recalc()
npolys -= npos; npolys -= npos;
// Handle the connection. // Handle the connection.
if (m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)) if (m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos) == DT_SUCCESS)
{ {
if (m_nsmoothPath < MAX_SMOOTH) if (m_nsmoothPath < MAX_SMOOTH)
{ {
@ -679,7 +681,7 @@ void NavMeshTesterTool::recalc()
m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2], m_spos[0],m_spos[1],m_spos[2], m_epos[0],m_epos[1],m_epos[2],
m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif #endif
m_npolys = m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS); m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, &m_npolys, MAX_POLYS);
m_nstraightPath = 0; m_nstraightPath = 0;
if (m_npolys) if (m_npolys)
{ {
@ -689,9 +691,9 @@ void NavMeshTesterTool::recalc()
if (m_polys[m_npolys-1] != m_endRef) if (m_polys[m_npolys-1] != m_endRef)
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos); m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos);
m_nstraightPath = m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys, m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
m_straightPath, m_straightPathFlags, m_straightPath, m_straightPathFlags,
m_straightPathPolys, MAX_POLYS); m_straightPathPolys, &m_nstraightPath, MAX_POLYS);
} }
} }
else else
@ -712,7 +714,7 @@ void NavMeshTesterTool::recalc()
m_npolys = 0; m_npolys = 0;
m_nstraightPath = 0; m_nstraightPath = 0;
m_pathFindState = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter); m_pathFindStatus = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter);
} }
else else
{ {
@ -736,7 +738,7 @@ void NavMeshTesterTool::recalc()
m_straightPath[0] = m_spos[0]; m_straightPath[0] = m_spos[0];
m_straightPath[1] = m_spos[1]; m_straightPath[1] = m_spos[1];
m_straightPath[2] = m_spos[2]; m_straightPath[2] = m_spos[2];
m_npolys = m_navQuery->raycast(m_startRef, m_spos, m_epos, &m_filter, t, m_hitNormal, m_polys, MAX_POLYS); m_navQuery->raycast(m_startRef, m_spos, m_epos, &m_filter, &t, m_hitNormal, m_polys, &m_npolys, MAX_POLYS);
if (t > 1) if (t > 1)
{ {
// No hit // No hit
@ -770,7 +772,8 @@ void NavMeshTesterTool::recalc()
m_spos[0],m_spos[1],m_spos[2], 100.0f, m_spos[0],m_spos[1],m_spos[2], 100.0f,
m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif #endif
m_distanceToWall = m_navQuery->findDistanceToWall(m_startRef, m_spos, 100.0f, &m_filter, m_hitPos, m_hitNormal); m_distanceToWall = 0.0f;
m_navQuery->findDistanceToWall(m_startRef, m_spos, 100.0f, &m_filter, &m_distanceToWall, m_hitPos, m_hitNormal);
} }
} }
else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_CIRCLE) else if (m_toolMode == TOOLMODE_FIND_POLYS_IN_CIRCLE)
@ -785,8 +788,8 @@ void NavMeshTesterTool::recalc()
m_spos[0],m_spos[1],m_spos[2], dist, m_spos[0],m_spos[1],m_spos[2], dist,
m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif #endif
m_npolys = m_navQuery->findPolysAroundCircle(m_startRef, m_spos, dist, &m_filter, m_navQuery->findPolysAroundCircle(m_startRef, m_spos, dist, &m_filter,
m_polys, m_parent, 0, MAX_POLYS); m_polys, m_parent, 0, &m_npolys, MAX_POLYS);
} }
} }
@ -822,8 +825,8 @@ void NavMeshTesterTool::recalc()
m_queryPoly[9],m_queryPoly[10],m_queryPoly[11], m_queryPoly[9],m_queryPoly[10],m_queryPoly[11],
m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif #endif
m_npolys = m_navQuery->findPolysAroundShape(m_startRef, m_queryPoly, 4, &m_filter, m_navQuery->findPolysAroundShape(m_startRef, m_queryPoly, 4, &m_filter,
m_polys, m_parent, 0, MAX_POLYS); m_polys, m_parent, 0, &m_npolys, MAX_POLYS);
} }
} }
else if (m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD) else if (m_toolMode == TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD)
@ -835,8 +838,8 @@ void NavMeshTesterTool::recalc()
m_spos[0],m_spos[1],m_spos[2], m_neighbourhoodRadius, m_spos[0],m_spos[1],m_spos[2], m_neighbourhoodRadius,
m_filter.getIncludeFlags(), m_filter.getExcludeFlags()); m_filter.getIncludeFlags(), m_filter.getExcludeFlags());
#endif #endif
m_npolys = m_navQuery->findLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, &m_filter, m_navQuery->findLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, &m_filter,
m_polys, m_parent, MAX_POLYS); m_polys, m_parent, &m_npolys, MAX_POLYS);
} }
} }
} }
@ -849,7 +852,7 @@ static void getPolyCenter(dtNavMesh* navMesh, dtPolyRef ref, float* center)
const dtMeshTile* tile = 0; const dtMeshTile* tile = 0;
const dtPoly* poly = 0; const dtPoly* poly = 0;
if (!navMesh->getTileAndPolyByRef(ref, &tile, &poly)) if (navMesh->getTileAndPolyByRef(ref, &tile, &poly) != DT_SUCCESS)
return; return;
for (int i = 0; i < (int)poly->vertCount; ++i) for (int i = 0; i < (int)poly->vertCount; ++i)
@ -1120,7 +1123,8 @@ void NavMeshTesterTool::handleRender()
static const int MAX_SEGS = DT_VERTS_PER_POLYGON*2; static const int MAX_SEGS = DT_VERTS_PER_POLYGON*2;
float segs[MAX_SEGS*6]; float segs[MAX_SEGS*6];
const int nsegs = m_navQuery->getPolyWallSegments(m_polys[i], &m_filter, segs, MAX_SEGS); int nsegs = 0;
m_navQuery->getPolyWallSegments(m_polys[i], &m_filter, segs, &nsegs, MAX_SEGS);
dd.begin(DU_DRAW_LINES, 2.0f); dd.begin(DU_DRAW_LINES, 2.0f);
for (int j = 0; j < nsegs; ++j) for (int j = 0; j < nsegs; ++j)
{ {

View File

@ -639,14 +639,14 @@ bool Sample_SoloMeshSimple::handleBuild()
return false; return false;
} }
if (!m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA)) if (m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA) != DT_SUCCESS)
{ {
dtFree(navData); dtFree(navData);
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh"); m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh");
return false; return false;
} }
if (!m_navQuery->init(m_navMesh, 2048)) if (m_navQuery->init(m_navMesh, 2048) != DT_SUCCESS)
{ {
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query"); m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
return false; return false;

View File

@ -1079,14 +1079,14 @@ bool Sample_SoloMeshTiled::handleBuild()
return false; return false;
} }
if (!m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA)) if (m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA) != DT_SUCCESS)
{ {
dtFree(navData); dtFree(navData);
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh"); m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh");
return false; return false;
} }
if (!m_navQuery->init(m_navMesh, 2048)) if (m_navQuery->init(m_navMesh, 2048) != DT_SUCCESS)
{ {
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query"); m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
return false; return false;

View File

@ -295,7 +295,7 @@ dtNavMesh* Sample_TileMesh::loadAll(const char* path)
dtNavMesh* mesh = dtAllocNavMesh(); dtNavMesh* mesh = dtAllocNavMesh();
if (!mesh || !mesh->init(&header.params)) if (!mesh || mesh->init(&header.params) != DT_SUCCESS)
{ {
fclose(fp); fclose(fp);
return 0; return 0;
@ -314,7 +314,7 @@ dtNavMesh* Sample_TileMesh::loadAll(const char* path)
memset(data, 0, tileHeader.dataSize); memset(data, 0, tileHeader.dataSize);
fread(data, tileHeader.dataSize, 1, fp); fread(data, tileHeader.dataSize, 1, fp);
mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef); mesh->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);
} }
fclose(fp); fclose(fp);
@ -710,13 +710,13 @@ bool Sample_TileMesh::handleBuild()
params.tileHeight = m_tileSize*m_cellSize; params.tileHeight = m_tileSize*m_cellSize;
params.maxTiles = m_maxTiles; params.maxTiles = m_maxTiles;
params.maxPolys = m_maxPolysPerTile; params.maxPolys = m_maxPolysPerTile;
if (!m_navMesh->init(&params)) if (m_navMesh->init(&params) != DT_SUCCESS)
{ {
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh."); m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh.");
return false; return false;
} }
if (!m_navQuery->init(m_navMesh, 2048)) if (m_navQuery->init(m_navMesh, 2048) != DT_SUCCESS)
{ {
m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init Detour navmesh query"); m_ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init Detour navmesh query");
return false; return false;
@ -764,7 +764,7 @@ void Sample_TileMesh::buildTile(const float* pos)
m_navMesh->removeTile(m_navMesh->getTileRefAt(tx,ty),0,0); m_navMesh->removeTile(m_navMesh->getTileRefAt(tx,ty),0,0);
// Let the navmesh own the data. // Let the navmesh own the data.
if (!m_navMesh->addTile(data,dataSize,DT_TILE_FREE_DATA)) if (m_navMesh->addTile(data,dataSize,DT_TILE_FREE_DATA,0,0) != DT_SUCCESS)
dtFree(data); dtFree(data);
} }
@ -844,7 +844,7 @@ void Sample_TileMesh::buildAllTiles()
// Remove any previous data (navmesh owns and deletes the data). // Remove any previous data (navmesh owns and deletes the data).
m_navMesh->removeTile(m_navMesh->getTileRefAt(x,y),0,0); m_navMesh->removeTile(m_navMesh->getTileRefAt(x,y),0,0);
// Let the navmesh own the data. // Let the navmesh own the data.
if (!m_navMesh->addTile(data,dataSize,true)) if (m_navMesh->addTile(data,dataSize,DT_TILE_FREE_DATA,0,0) != DT_SUCCESS)
dtFree(data); dtFree(data);
} }
} }

View File

@ -186,8 +186,9 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
// Find start points // Find start points
TimeVal findNearestPolyStart = getPerfTime(); TimeVal findNearestPolyStart = getPerfTime();
dtPolyRef startRef = navquery->findNearestPoly(iter->spos, polyPickExt, &filter, 0); dtPolyRef startRef, endRef;
dtPolyRef endRef = navquery->findNearestPoly(iter->epos, polyPickExt, &filter, 0); navquery->findNearestPoly(iter->spos, polyPickExt, &filter, &startRef, 0);
navquery->findNearestPoly(iter->epos, polyPickExt, &filter, &endRef, 0);
TimeVal findNearestPolyEnd = getPerfTime(); TimeVal findNearestPolyEnd = getPerfTime();
iter->findNearestPolyTime += getPerfDeltaTimeUsec(findNearestPolyStart, findNearestPolyEnd); iter->findNearestPolyTime += getPerfDeltaTimeUsec(findNearestPolyStart, findNearestPolyEnd);
@ -198,7 +199,7 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
// Find path // Find path
TimeVal findPathStart = getPerfTime(); TimeVal findPathStart = getPerfTime();
iter->npolys = navquery->findPath(startRef, endRef, iter->spos, iter->epos, &filter, polys, MAX_POLYS); navquery->findPath(startRef, endRef, iter->spos, iter->epos, &filter, polys, &iter->npolys, MAX_POLYS);
TimeVal findPathEnd = getPerfTime(); TimeVal findPathEnd = getPerfTime();
iter->findPathTime += getPerfDeltaTimeUsec(findPathStart, findPathEnd); iter->findPathTime += getPerfDeltaTimeUsec(findPathStart, findPathEnd);
@ -208,8 +209,8 @@ void TestCase::doTests(dtNavMesh* navmesh, dtNavMeshQuery* navquery)
{ {
TimeVal findStraightPathStart = getPerfTime(); TimeVal findStraightPathStart = getPerfTime();
iter->nstraight = navquery->findStraightPath(iter->spos, iter->epos, polys, iter->npolys, navquery->findStraightPath(iter->spos, iter->epos, polys, iter->npolys,
straight, 0, 0, MAX_POLYS); straight, 0, 0, &iter->nstraight, MAX_POLYS);
TimeVal findStraightPathEnd = getPerfTime(); TimeVal findStraightPathEnd = getPerfTime();
iter->findStraightPathTime += getPerfDeltaTimeUsec(findStraightPathStart, findStraightPathEnd); iter->findStraightPathTime += getPerfDeltaTimeUsec(findStraightPathStart, findStraightPathEnd);
} }