Unverified Commit 41ac6cfa by Rémi Verschelde Committed by GitHub

Merge pull request #38364 from akien-mga/recast-57610fa

Recast: Update to upstream commit 57610fa (2019)
parents f8701183 6ba546f9
...@@ -485,12 +485,12 @@ Files extracted from upstream source: ...@@ -485,12 +485,12 @@ Files extracted from upstream source:
## recastnavigation ## recastnavigation
- Upstream: https://github.com/recastnavigation/recastnavigation - Upstream: https://github.com/recastnavigation/recastnavigation
- Version: git (ef3ea40f, 2017) - Version: git (57610fa6ef31b39020231906f8c5d40eaa8294ae, 2019)
- License: zlib - License: zlib
Files extracted from upstream source: Files extracted from upstream source:
- `Recast/` folder - `Recast/` folder without `CMakeLists.txt`
- License.txt - License.txt
......
...@@ -332,6 +332,8 @@ struct rcCompactSpan ...@@ -332,6 +332,8 @@ struct rcCompactSpan
/// @ingroup recast /// @ingroup recast
struct rcCompactHeightfield struct rcCompactHeightfield
{ {
rcCompactHeightfield();
~rcCompactHeightfield();
int width; ///< The width of the heightfield. (Along the x-axis in cell units.) int width; ///< The width of the heightfield. (Along the x-axis in cell units.)
int height; ///< The height of the heightfield. (Along the z-axis in cell units.) int height; ///< The height of the heightfield. (Along the z-axis in cell units.)
int spanCount; ///< The number of spans in the heightfield. int spanCount; ///< The number of spans in the heightfield.
...@@ -376,6 +378,8 @@ struct rcHeightfieldLayer ...@@ -376,6 +378,8 @@ struct rcHeightfieldLayer
/// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet /// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet
struct rcHeightfieldLayerSet struct rcHeightfieldLayerSet
{ {
rcHeightfieldLayerSet();
~rcHeightfieldLayerSet();
rcHeightfieldLayer* layers; ///< The layers in the set. [Size: #nlayers] rcHeightfieldLayer* layers; ///< The layers in the set. [Size: #nlayers]
int nlayers; ///< The number of layers in the set. int nlayers; ///< The number of layers in the set.
}; };
...@@ -395,6 +399,8 @@ struct rcContour ...@@ -395,6 +399,8 @@ struct rcContour
/// @ingroup recast /// @ingroup recast
struct rcContourSet struct rcContourSet
{ {
rcContourSet();
~rcContourSet();
rcContour* conts; ///< An array of the contours in the set. [Size: #nconts] rcContour* conts; ///< An array of the contours in the set. [Size: #nconts]
int nconts; ///< The number of contours in the set. int nconts; ///< The number of contours in the set.
float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
...@@ -411,6 +417,8 @@ struct rcContourSet ...@@ -411,6 +417,8 @@ struct rcContourSet
/// @ingroup recast /// @ingroup recast
struct rcPolyMesh struct rcPolyMesh
{ {
rcPolyMesh();
~rcPolyMesh();
unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts] unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts]
unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp] unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp]
unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys] unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys]
......
...@@ -23,11 +23,34 @@ ...@@ -23,11 +23,34 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <new>
#include "Recast.h" #include "Recast.h"
#include "RecastAlloc.h" #include "RecastAlloc.h"
#include "RecastAssert.h" #include "RecastAssert.h"
namespace
{
/// Allocates and constructs an object of the given type, returning a pointer.
/// TODO: Support constructor args.
/// @param[in] hint Hint to the allocator.
template <typename T>
T* rcNew(rcAllocHint hint) {
T* ptr = (T*)rcAlloc(sizeof(T), hint);
::new(rcNewTag(), (void*)ptr) T();
return ptr;
}
/// Destroys and frees an object allocated with rcNew.
/// @param[in] ptr The object pointer to delete.
template <typename T>
void rcDelete(T* ptr) {
if (ptr) {
ptr->~T();
rcFree((void*)ptr);
}
}
} // namespace
float rcSqrt(float x) float rcSqrt(float x)
{ {
return sqrtf(x); return sqrtf(x);
...@@ -73,9 +96,8 @@ void rcContext::log(const rcLogCategory category, const char* format, ...) ...@@ -73,9 +96,8 @@ void rcContext::log(const rcLogCategory category, const char* format, ...)
rcHeightfield* rcAllocHeightfield() rcHeightfield* rcAllocHeightfield()
{ {
return new (rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM)) rcHeightfield; return rcNew<rcHeightfield>(RC_ALLOC_PERM);
} }
rcHeightfield::rcHeightfield() rcHeightfield::rcHeightfield()
: width() : width()
, height() , height()
...@@ -104,84 +126,133 @@ rcHeightfield::~rcHeightfield() ...@@ -104,84 +126,133 @@ rcHeightfield::~rcHeightfield()
void rcFreeHeightField(rcHeightfield* hf) void rcFreeHeightField(rcHeightfield* hf)
{ {
if (!hf) return; rcDelete(hf);
hf->~rcHeightfield();
rcFree(hf);
} }
rcCompactHeightfield* rcAllocCompactHeightfield() rcCompactHeightfield* rcAllocCompactHeightfield()
{ {
rcCompactHeightfield* chf = (rcCompactHeightfield*)rcAlloc(sizeof(rcCompactHeightfield), RC_ALLOC_PERM); return rcNew<rcCompactHeightfield>(RC_ALLOC_PERM);
memset(chf, 0, sizeof(rcCompactHeightfield));
return chf;
} }
void rcFreeCompactHeightfield(rcCompactHeightfield* chf) void rcFreeCompactHeightfield(rcCompactHeightfield* chf)
{ {
if (!chf) return; rcDelete(chf);
rcFree(chf->cells);
rcFree(chf->spans);
rcFree(chf->dist);
rcFree(chf->areas);
rcFree(chf);
} }
rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet() rcCompactHeightfield::rcCompactHeightfield()
: width(),
height(),
spanCount(),
walkableHeight(),
walkableClimb(),
borderSize(),
maxDistance(),
maxRegions(),
bmin(),
bmax(),
cs(),
ch(),
cells(),
spans(),
dist(),
areas()
{ {
rcHeightfieldLayerSet* lset = (rcHeightfieldLayerSet*)rcAlloc(sizeof(rcHeightfieldLayerSet), RC_ALLOC_PERM); }
memset(lset, 0, sizeof(rcHeightfieldLayerSet)); rcCompactHeightfield::~rcCompactHeightfield()
return lset; {
rcFree(cells);
rcFree(spans);
rcFree(dist);
rcFree(areas);
} }
rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet()
{
return rcNew<rcHeightfieldLayerSet>(RC_ALLOC_PERM);
}
void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset) void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset)
{ {
if (!lset) return; rcDelete(lset);
for (int i = 0; i < lset->nlayers; ++i) }
rcHeightfieldLayerSet::rcHeightfieldLayerSet()
: layers(), nlayers() {}
rcHeightfieldLayerSet::~rcHeightfieldLayerSet()
{
for (int i = 0; i < nlayers; ++i)
{ {
rcFree(lset->layers[i].heights); rcFree(layers[i].heights);
rcFree(lset->layers[i].areas); rcFree(layers[i].areas);
rcFree(lset->layers[i].cons); rcFree(layers[i].cons);
} }
rcFree(lset->layers); rcFree(layers);
rcFree(lset);
} }
rcContourSet* rcAllocContourSet() rcContourSet* rcAllocContourSet()
{ {
rcContourSet* cset = (rcContourSet*)rcAlloc(sizeof(rcContourSet), RC_ALLOC_PERM); return rcNew<rcContourSet>(RC_ALLOC_PERM);
memset(cset, 0, sizeof(rcContourSet));
return cset;
} }
void rcFreeContourSet(rcContourSet* cset) void rcFreeContourSet(rcContourSet* cset)
{ {
if (!cset) return; rcDelete(cset);
for (int i = 0; i < cset->nconts; ++i) }
rcContourSet::rcContourSet()
: conts(),
nconts(),
bmin(),
bmax(),
cs(),
ch(),
width(),
height(),
borderSize(),
maxError() {}
rcContourSet::~rcContourSet()
{
for (int i = 0; i < nconts; ++i)
{ {
rcFree(cset->conts[i].verts); rcFree(conts[i].verts);
rcFree(cset->conts[i].rverts); rcFree(conts[i].rverts);
} }
rcFree(cset->conts); rcFree(conts);
rcFree(cset);
} }
rcPolyMesh* rcAllocPolyMesh() rcPolyMesh* rcAllocPolyMesh()
{ {
rcPolyMesh* pmesh = (rcPolyMesh*)rcAlloc(sizeof(rcPolyMesh), RC_ALLOC_PERM); return rcNew<rcPolyMesh>(RC_ALLOC_PERM);
memset(pmesh, 0, sizeof(rcPolyMesh));
return pmesh;
} }
void rcFreePolyMesh(rcPolyMesh* pmesh) void rcFreePolyMesh(rcPolyMesh* pmesh)
{ {
if (!pmesh) return; rcDelete(pmesh);
rcFree(pmesh->verts); }
rcFree(pmesh->polys);
rcFree(pmesh->regs); rcPolyMesh::rcPolyMesh()
rcFree(pmesh->flags); : verts(),
rcFree(pmesh->areas); polys(),
rcFree(pmesh); regs(),
flags(),
areas(),
nverts(),
npolys(),
maxpolys(),
nvp(),
bmin(),
bmax(),
cs(),
ch(),
borderSize(),
maxEdgeError() {}
rcPolyMesh::~rcPolyMesh()
{
rcFree(verts);
rcFree(polys);
rcFree(regs);
rcFree(flags);
rcFree(areas);
} }
rcPolyMeshDetail* rcAllocPolyMeshDetail() rcPolyMeshDetail* rcAllocPolyMeshDetail()
......
...@@ -58,29 +58,3 @@ void rcFree(void* ptr) ...@@ -58,29 +58,3 @@ void rcFree(void* ptr)
if (ptr) if (ptr)
sRecastFreeFunc(ptr); sRecastFreeFunc(ptr);
} }
/// @class rcIntArray
///
/// While it is possible to pre-allocate a specific array size during
/// construction or by using the #resize method, certain methods will
/// automatically resize the array as needed.
///
/// @warning The array memory is not initialized to zero when the size is
/// manually set during construction or when using #resize.
/// @par
///
/// Using this method ensures the array is at least large enough to hold
/// the specified number of elements. This can improve performance by
/// avoiding auto-resizing during use.
void rcIntArray::doResize(int n)
{
if (!m_cap) m_cap = n;
while (m_cap < n) m_cap *= 2;
int* newData = (int*)rcAlloc(m_cap*sizeof(int), RC_ALLOC_TEMP);
rcAssert(newData);
if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(int));
rcFree(m_data);
m_data = newData;
}
...@@ -1009,7 +1009,7 @@ bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf, ...@@ -1009,7 +1009,7 @@ bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
if (cset.nconts > 0) if (cset.nconts > 0)
{ {
// Calculate winding of all polygons. // Calculate winding of all polygons.
rcScopedDelete<char> winding((char*)rcAlloc(sizeof(char)*cset.nconts, RC_ALLOC_TEMP)); rcScopedDelete<signed char> winding((signed char*)rcAlloc(sizeof(signed char)*cset.nconts, RC_ALLOC_TEMP));
if (!winding) if (!winding)
{ {
ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'hole' (%d).", cset.nconts); ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'hole' (%d).", cset.nconts);
......
...@@ -557,15 +557,16 @@ static float polyMinExtent(const float* verts, const int nverts) ...@@ -557,15 +557,16 @@ static float polyMinExtent(const float* verts, const int nverts)
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; } inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; } inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, rcIntArray& tris) static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, const int nin, rcIntArray& tris)
{ {
int start = 0, left = 1, right = nhull-1; int start = 0, left = 1, right = nhull-1;
// Start from an ear with shortest perimeter. // Start from an ear with shortest perimeter.
// This tends to favor well formed triangles as starting point. // This tends to favor well formed triangles as starting point.
float dmin = 0; float dmin = FLT_MAX;
for (int i = 0; i < nhull; i++) for (int i = 0; i < nhull; i++)
{ {
if (hull[i] >= nin) continue; // Ears are triangles with original vertices as middle vertex while others are actually line segments on edges
int pi = prev(i, nhull); int pi = prev(i, nhull);
int ni = next(i, nhull); int ni = next(i, nhull);
const float* pv = &verts[hull[pi]*3]; const float* pv = &verts[hull[pi]*3];
...@@ -770,7 +771,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin, ...@@ -770,7 +771,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
// If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points. // If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points.
if (minExtent < sampleDist*2) if (minExtent < sampleDist*2)
{ {
triangulateHull(nverts, verts, nhull, hull, tris); triangulateHull(nverts, verts, nhull, hull, nin, tris);
return true; return true;
} }
...@@ -778,7 +779,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin, ...@@ -778,7 +779,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
// We're using the triangulateHull instead of delaunayHull as it tends to // We're using the triangulateHull instead of delaunayHull as it tends to
// create a bit better triangulation for long thin triangles when there // create a bit better triangulation for long thin triangles when there
// are no internal points. // are no internal points.
triangulateHull(nverts, verts, nhull, hull, tris); triangulateHull(nverts, verts, nhull, hull, nin, tris);
if (tris.size() == 0) if (tris.size() == 0)
{ {
...@@ -1140,7 +1141,8 @@ static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf, ...@@ -1140,7 +1141,8 @@ static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf,
static unsigned char getEdgeFlags(const float* va, const float* vb, static unsigned char getEdgeFlags(const float* va, const float* vb,
const float* vpoly, const int npoly) const float* vpoly, const int npoly)
{ {
// Return true if edge (va,vb) is part of the polygon. // The flag returned by this function matches dtDetailTriEdgeFlags in Detour.
// Figure out if edge (va,vb) is part of the polygon boundary.
static const float thrSqr = rcSqr(0.001f); static const float thrSqr = rcSqr(0.001f);
for (int i = 0, j = npoly-1; i < npoly; j=i++) for (int i = 0, j = npoly-1; i < npoly; j=i++)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment