mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Recast: make detail mesh edge detection more robust
Merge recastnavitagion/recastnavitagion@c393777d26 Instead of using a distance check which can fail at large magnitudes due to low precision we can check whether the edges are actually on the hull.
This commit is contained in:
parent
9254ac2de3
commit
23b856d3f5
@ -735,6 +735,40 @@ inline float getJitterY(const int i)
|
|||||||
return (((i * 0xd8163841) & 0xffff) / 65535.0f * 2.0f) - 1.0f;
|
return (((i * 0xd8163841) & 0xffff) / 65535.0f * 2.0f) - 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool onHull(int a, int b, int nhull, int* hull)
|
||||||
|
{
|
||||||
|
// All internal sampled points come after the hull so we can early out for those.
|
||||||
|
if (a >= nhull || b >= nhull)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int j = nhull - 1, i = 0; i < nhull; j = i++)
|
||||||
|
{
|
||||||
|
if (a == hull[j] && b == hull[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find edges that lie on hull and mark them as such.
|
||||||
|
static void setTriFlags(rcIntArray& tris, int nhull, int* hull)
|
||||||
|
{
|
||||||
|
// Matches DT_DETAIL_EDGE_BOUNDARY
|
||||||
|
const int DETAIL_EDGE_BOUNDARY = 0x1;
|
||||||
|
|
||||||
|
for (int i = 0; i < tris.size(); i += 4)
|
||||||
|
{
|
||||||
|
int a = tris[i + 0];
|
||||||
|
int b = tris[i + 2];
|
||||||
|
int c = tris[i + 1];
|
||||||
|
unsigned short flags = 0;
|
||||||
|
flags |= (onHull(a, b, nhull, hull) ? DETAIL_EDGE_BOUNDARY : 0) << 0;
|
||||||
|
flags |= (onHull(b, c, nhull, hull) ? DETAIL_EDGE_BOUNDARY : 0) << 2;
|
||||||
|
flags |= (onHull(c, a, nhull, hull) ? DETAIL_EDGE_BOUNDARY : 0) << 4;
|
||||||
|
tris[i + 3] = (int)flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
||||||
const float sampleDist, const float sampleMaxError,
|
const float sampleDist, const float sampleMaxError,
|
||||||
const int heightSearchRadius, const rcCompactHeightfield& chf,
|
const int heightSearchRadius, const rcCompactHeightfield& chf,
|
||||||
@ -872,6 +906,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
|||||||
if (minExtent < sampleDist*2)
|
if (minExtent < sampleDist*2)
|
||||||
{
|
{
|
||||||
triangulateHull(nverts, verts, nhull, hull, nin, tris);
|
triangulateHull(nverts, verts, nhull, hull, nin, tris);
|
||||||
|
setTriFlags(tris, nhull, hull);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -976,6 +1011,8 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
|||||||
tris.resize(MAX_TRIS*4);
|
tris.resize(MAX_TRIS*4);
|
||||||
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Shrinking triangle count from %d to max %d.", ntris, MAX_TRIS);
|
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Shrinking triangle count from %d to max %d.", ntris, MAX_TRIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTriFlags(tris, nhull, hull);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1238,31 +1275,6 @@ static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char getEdgeFlags(const float* va, const float* vb,
|
|
||||||
const float* vpoly, const int npoly)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
for (int i = 0, j = npoly-1; i < npoly; j=i++)
|
|
||||||
{
|
|
||||||
if (distancePtSeg2d(va, &vpoly[j*3], &vpoly[i*3]) < thrSqr &&
|
|
||||||
distancePtSeg2d(vb, &vpoly[j*3], &vpoly[i*3]) < thrSqr)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char getTriFlags(const float* va, const float* vb, const float* vc,
|
|
||||||
const float* vpoly, const int npoly)
|
|
||||||
{
|
|
||||||
unsigned char flags = 0;
|
|
||||||
flags |= getEdgeFlags(va,vb,vpoly,npoly) << 0;
|
|
||||||
flags |= getEdgeFlags(vb,vc,vpoly,npoly) << 2;
|
|
||||||
flags |= getEdgeFlags(vc,va,vpoly,npoly) << 4;
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// See the #rcConfig documentation for more information on the configuration parameters.
|
/// See the #rcConfig documentation for more information on the configuration parameters.
|
||||||
@ -1479,7 +1491,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
|
|||||||
dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0];
|
dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0];
|
||||||
dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[2];
|
dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[2];
|
||||||
dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[1];
|
dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[1];
|
||||||
dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[2]*3], &verts[t[1]*3], poly, npoly);
|
dmesh.tris[dmesh.ntris*4+3] = (unsigned char)t[3];
|
||||||
dmesh.ntris++;
|
dmesh.ntris++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user