This commit is contained in:
axelrodR 2014-06-24 22:55:04 +03:00
commit 86328ced48
5 changed files with 142 additions and 144 deletions

View File

@ -63,6 +63,8 @@ struct dtTileCacheParams
struct dtTileCacheMeshProcess struct dtTileCacheMeshProcess
{ {
virtual ~dtTileCacheMeshProcess() { }
virtual void process(struct dtNavMeshCreateParams* params, virtual void process(struct dtNavMeshCreateParams* params,
unsigned char* polyAreas, unsigned short* polyFlags) = 0; unsigned char* polyAreas, unsigned short* polyFlags) = 0;
}; };

View File

@ -78,6 +78,8 @@ struct dtTileCachePolyMesh
struct dtTileCacheAlloc struct dtTileCacheAlloc
{ {
virtual ~dtTileCacheAlloc() { }
virtual void reset() virtual void reset()
{ {
} }
@ -95,6 +97,8 @@ struct dtTileCacheAlloc
struct dtTileCacheCompressor struct dtTileCacheCompressor
{ {
virtual ~dtTileCacheCompressor() { }
virtual int maxCompressedSize(const int bufferSize) = 0; virtual int maxCompressedSize(const int bufferSize) = 0;
virtual dtStatus compress(const unsigned char* buffer, const int bufferSize, virtual dtStatus compress(const unsigned char* buffer, const int bufferSize,
unsigned char* compressed, const int maxCompressedSize, int* compressedSize) = 0; unsigned char* compressed, const int maxCompressedSize, int* compressedSize) = 0;

View File

@ -188,27 +188,6 @@ static float distancePtSeg(const int x, const int z,
const int px, const int pz, const int px, const int pz,
const int qx, const int qz) const int qx, const int qz)
{ {
/* float pqx = (float)(qx - px);
float pqy = (float)(qy - py);
float pqz = (float)(qz - pz);
float dx = (float)(x - px);
float dy = (float)(y - py);
float dz = (float)(z - pz);
float d = pqx*pqx + pqy*pqy + pqz*pqz;
float t = pqx*dx + pqy*dy + pqz*dz;
if (d > 0)
t /= d;
if (t < 0)
t = 0;
else if (t > 1)
t = 1;
dx = px + t*pqx - x;
dy = py + t*pqy - y;
dz = pz + t*pqz - z;
return dx*dx + dy*dy + dz*dz;*/
float pqx = (float)(qx - px); float pqx = (float)(qx - px);
float pqz = (float)(qz - pz); float pqz = (float)(qz - pz);
float dx = (float)(x - px); float dx = (float)(x - px);
@ -1102,8 +1081,20 @@ bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
// Finally merge each regions holes into the outline. // Finally merge each regions holes into the outline.
for (int i = 0; i < nregions; i++) for (int i = 0; i < nregions; i++)
{ {
if (regions[i].nholes > 0) rcContourRegion& reg = regions[i];
mergeRegionHoles(ctx, regions[i]); if (!reg.nholes) continue;
if (reg.outline)
{
mergeRegionHoles(ctx, reg);
}
else
{
// The region does not have an outline.
// This can happen if the contour becaomes selfoverlapping because of
// too aggressive simplification settings.
ctx->log(RC_LOG_ERROR, "rcBuildContours: Bad outline for region %d, contour simplification is likely too aggressive.", i);
}
} }
} }

View File

@ -1537,7 +1537,7 @@ bool rcCopyPolyMesh(rcContext* ctx, const rcPolyMesh& src, rcPolyMesh& dst)
ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.flags' (%d).", src.npolys); ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.flags' (%d).", src.npolys);
return false; return false;
} }
memcpy(dst.flags, src.flags, sizeof(unsigned char)*src.npolys); memcpy(dst.flags, src.flags, sizeof(unsigned short)*src.npolys);
return true; return true;
} }

View File

@ -68,21 +68,27 @@ static bool circumCircle(const float* p1, const float* p2, const float* p3,
float* c, float& r) float* c, float& r)
{ {
static const float EPS = 1e-6f; static const float EPS = 1e-6f;
// Calculate the circle relative to p1, to avoid some precision issues.
const float v1[3] = {0,0,0};
float v2[3], v3[3];
rcVsub(v2, p2,p1);
rcVsub(v3, p3,p1);
const float cp = vcross2(p1, p2, p3); const float cp = vcross2(v1, v2, v3);
if (fabsf(cp) > EPS) if (fabsf(cp) > EPS)
{ {
const float p1Sq = vdot2(p1,p1); const float v1Sq = vdot2(v1,v1);
const float p2Sq = vdot2(p2,p2); const float v2Sq = vdot2(v2,v2);
const float p3Sq = vdot2(p3,p3); const float v3Sq = vdot2(v3,v3);
c[0] = (p1Sq*(p2[2]-p3[2]) + p2Sq*(p3[2]-p1[2]) + p3Sq*(p1[2]-p2[2])) / (2*cp); c[0] = (v1Sq*(v2[2]-v3[2]) + v2Sq*(v3[2]-v1[2]) + v3Sq*(v1[2]-v2[2])) / (2*cp);
c[2] = (p1Sq*(p3[0]-p2[0]) + p2Sq*(p1[0]-p3[0]) + p3Sq*(p2[0]-p1[0])) / (2*cp); c[1] = 0;
r = vdist2(c, p1); c[2] = (v1Sq*(v3[0]-v2[0]) + v2Sq*(v1[0]-v3[0]) + v3Sq*(v2[0]-v1[0])) / (2*cp);
r = vdist2(c, v1);
rcVadd(c, c, p1);
return true; return true;
} }
c[0] = p1[0]; rcVcopy(c, p1);
c[2] = p1[2];
r = 0; r = 0;
return false; return false;
} }
@ -223,15 +229,6 @@ static unsigned short getHeight(const float fx, const float fy, const float fz,
h = nh; h = nh;
dmin = d; dmin = d;
} }
/* const float dx = (nx+0.5f)*cs - fx;
const float dz = (nz+0.5f)*cs - fz;
const float d = dx*dx+dz*dz;
if (d < dmin)
{
h = nh;
dmin = d;
} */
} }
} }
return h; return h;
@ -524,15 +521,17 @@ static void triangulateHull(const int nverts, const float* verts, const int nhul
{ {
int start = 0, left = 1, right = nhull-1; int start = 0, left = 1, right = nhull-1;
// Start from shortest ear. // Start from an ear with shortest perimeter.
float dmin = FLT_MAX; // This tends to favor well formed triangles as starting point.
float dmin = 0;
for (int i = 0; i < nhull; i++) for (int i = 0; i < nhull; i++)
{ {
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];
const float* cv = &verts[hull[i]*3];
const float* nv = &verts[hull[ni]*3]; const float* nv = &verts[hull[ni]*3];
const float d = vdistSq2(pv, nv); const float d = vdist2(pv,cv) + vdist2(cv,nv) + vdist2(nv,pv);
if (d < dmin) if (d < dmin)
{ {
start = i; start = i;
@ -548,8 +547,10 @@ static void triangulateHull(const int nverts, const float* verts, const int nhul
tris.push(hull[right]); tris.push(hull[right]);
tris.push(0); tris.push(0);
// Triangulate the polygon by adding the shortest diagonal // Triangulate the polygon by moving left or right,
// by moving left or right. // depending on which triangle has shorter perimeter.
// This heuristic was chose emprically, since it seems
// handle tesselated straight edges well.
while (next(left, nhull) != right) while (next(left, nhull) != right)
{ {
// Check to see if se should advance left or right. // Check to see if se should advance left or right.
@ -560,9 +561,9 @@ static void triangulateHull(const int nverts, const float* verts, const int nhul
const float* nvleft = &verts[hull[nleft]*3]; const float* nvleft = &verts[hull[nleft]*3];
const float* cvright = &verts[hull[right]*3]; const float* cvright = &verts[hull[right]*3];
const float* nvright = &verts[hull[nright]*3]; const float* nvright = &verts[hull[nright]*3];
const float dleft = vdist2(cvleft, nvleft) + vdist2(nvleft, cvright);
const float dright = vdist2(cvright, nvright) + vdist2(cvleft, nvright);
const float dleft = vdistSq2(nvleft, cvright);
const float dright = vdistSq2(cvleft, nvright);
if (dleft < dright) if (dleft < dright)
{ {
tris.push(hull[left]); tris.push(hull[left]);
@ -1217,7 +1218,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
return false; return false;
} }
dmesh.ntris = 0; dmesh.ntris = 0;
dmesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char*)*tcap*4, RC_ALLOC_PERM); dmesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char)*tcap*4, RC_ALLOC_PERM);
if (!dmesh.tris) if (!dmesh.tris)
{ {
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4); ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4);