[Build] More Project build cleanup

This commit is contained in:
Antz 2015-02-07 20:36:45 +00:00 committed by Antz
parent d258cc922a
commit 4613154144
565 changed files with 26862 additions and 109982 deletions

View file

@ -59,6 +59,7 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
unsigned short* t = &polys[i*vertsPerPoly*2];
for (int j = 0; j < vertsPerPoly; ++j)
{
if (t[j] == RC_MESH_NULL_IDX) break;
unsigned short v0 = t[j];
unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1];
if (v0 < v1)
@ -83,6 +84,7 @@ static bool buildMeshAdjacency(unsigned short* polys, const int npolys,
unsigned short* t = &polys[i*vertsPerPoly*2];
for (int j = 0; j < vertsPerPoly; ++j)
{
if (t[j] == RC_MESH_NULL_IDX) break;
unsigned short v0 = t[j];
unsigned short v1 = (j+1 >= vertsPerPoly || t[j+1] == RC_MESH_NULL_IDX) ? t[0] : t[j+1];
if (v0 > v1)
@ -195,7 +197,7 @@ inline bool collinear(const int* a, const int* b, const int* c)
// Returns true iff ab properly intersects cd: they share
// a point interior to both segments. The properness of the
// intersection is ensured by using strict leftness.
bool intersectProp(const int* a, const int* b, const int* c, const int* d)
static bool intersectProp(const int* a, const int* b, const int* c, const int* d)
{
// Eliminate improper cases.
if (collinear(a,b,c) || collinear(a,b,d) ||
@ -286,6 +288,53 @@ static bool diagonal(int i, int j, int n, const int* verts, int* indices)
return inCone(i, j, n, verts, indices) && diagonalie(i, j, n, verts, indices);
}
static bool diagonalieLoose(int i, int j, int n, const int* verts, int* indices)
{
const int* d0 = &verts[(indices[i] & 0x0fffffff) * 4];
const int* d1 = &verts[(indices[j] & 0x0fffffff) * 4];
// For each edge (k,k+1) of P
for (int k = 0; k < n; k++)
{
int k1 = next(k, n);
// Skip edges incident to i or j
if (!((k == i) || (k1 == i) || (k == j) || (k1 == j)))
{
const int* p0 = &verts[(indices[k] & 0x0fffffff) * 4];
const int* p1 = &verts[(indices[k1] & 0x0fffffff) * 4];
if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1))
continue;
if (intersectProp(d0, d1, p0, p1))
return false;
}
}
return true;
}
static bool inConeLoose(int i, int j, int n, const int* verts, int* indices)
{
const int* pi = &verts[(indices[i] & 0x0fffffff) * 4];
const int* pj = &verts[(indices[j] & 0x0fffffff) * 4];
const int* pi1 = &verts[(indices[next(i, n)] & 0x0fffffff) * 4];
const int* pin1 = &verts[(indices[prev(i, n)] & 0x0fffffff) * 4];
// If P[i] is a convex vertex [ i+1 left or on (i-1,i) ].
if (leftOn(pin1, pi, pi1))
return leftOn(pi, pj, pin1) && leftOn(pj, pi, pi1);
// Assume (i-1,i,i+1) not collinear.
// else P[i] is reflex.
return !(leftOn(pi, pj, pi1) && leftOn(pj, pi, pin1));
}
static bool diagonalLoose(int i, int j, int n, const int* verts, int* indices)
{
return inConeLoose(i, j, n, verts, indices) && diagonalieLoose(i, j, n, verts, indices);
}
static int triangulate(int n, const int* verts, int* indices, int* tris)
{
int ntris = 0;
@ -326,14 +375,41 @@ static int triangulate(int n, const int* verts, int* indices, int* tris)
if (mini == -1)
{
// Should not happen.
/* printf("mini == -1 ntris=%d n=%d\n", ntris, n);
// We might get here because the contour has overlapping segments, like this:
//
// A o-o=====o---o B
// / |C D| \
// o o o o
// : : : :
// We'll try to recover by loosing up the inCone test a bit so that a diagonal
// like A-B or C-D can be found and we can continue.
minLen = -1;
mini = -1;
for (int i = 0; i < n; i++)
{
printf("%d ", indices[i] & 0x0fffffff);
int i1 = next(i, n);
int i2 = next(i1, n);
if (diagonalLoose(i, i2, n, verts, indices))
{
const int* p0 = &verts[(indices[i] & 0x0fffffff) * 4];
const int* p2 = &verts[(indices[next(i2, n)] & 0x0fffffff) * 4];
int dx = p2[0] - p0[0];
int dy = p2[2] - p0[2];
int len = dx*dx + dy*dy;
if (minLen < 0 || len < minLen)
{
minLen = len;
mini = i;
}
}
}
if (mini == -1)
{
// The contour is messed up. This sometimes happens
// if the contour simplification is too aggressive.
return -ntris;
}
printf("\n");*/
return -ntris;
}
int i = mini;
@ -470,6 +546,7 @@ static void mergePolys(unsigned short* pa, unsigned short* pb, int ea, int eb,
memcpy(pa, tmp, sizeof(unsigned short)*nvp);
}
static void pushFront(int v, int* arr, int& an)
{
an++;
@ -547,9 +624,9 @@ static bool canRemoveVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned sho
// Check if the edge exists
bool exists = false;
for (int k = 0; k < nedges; ++k)
for (int m = 0; m < nedges; ++m)
{
int* e = &edges[k*3];
int* e = &edges[m*3];
if (e[1] == b)
{
// Exists, increment vertex share count.
@ -658,7 +735,8 @@ static bool removeVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short
}
// Remove the polygon.
unsigned short* p2 = &mesh.polys[(mesh.npolys-1)*nvp*2];
memcpy(p,p2,sizeof(unsigned short)*nvp);
if (p != p2)
memcpy(p,p2,sizeof(unsigned short)*nvp);
memset(p+nvp,0xff,sizeof(unsigned short)*nvp);
mesh.regs[i] = mesh.regs[mesh.npolys-1];
mesh.areas[i] = mesh.areas[mesh.npolys-1];
@ -858,7 +936,9 @@ static bool removeVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short
unsigned short* pa = &polys[bestPa*nvp];
unsigned short* pb = &polys[bestPb*nvp];
mergePolys(pa, pb, bestEa, bestEb, tmpPoly, nvp);
memcpy(pb, &polys[(npolys-1)*nvp], sizeof(unsigned short)*nvp);
unsigned short* last = &polys[(npolys-1)*nvp];
if (pb != last)
memcpy(pb, last, sizeof(unsigned short)*nvp);
pregs[bestPb] = pregs[npolys-1];
pareas[bestPb] = pareas[npolys-1];
npolys--;
@ -892,8 +972,13 @@ static bool removeVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short
return true;
}
bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& mesh)
/// @par
///
/// @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper
/// limit must be retricted to <= #DT_VERTS_PER_POLYGON.
///
/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig
bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh)
{
rcAssert(ctx);
@ -903,6 +988,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
rcVcopy(mesh.bmax, cset.bmax);
mesh.cs = cset.cs;
mesh.ch = cset.ch;
mesh.borderSize = cset.borderSize;
int maxVertices = 0;
int maxTris = 0;
@ -925,7 +1011,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
rcScopedDelete<unsigned char> vflags = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxVertices, RC_ALLOC_TEMP);
if (!vflags)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vflags' (%d).", maxVertices);
return false;
}
memset(vflags, 0, maxVertices);
@ -936,7 +1022,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
return false;
}
mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris*nvp*2*2, RC_ALLOC_PERM);
mesh.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxTris*nvp*2, RC_ALLOC_PERM);
if (!mesh.polys)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2);
@ -1044,7 +1130,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
vflags[indices[j]] = 1;
}
}
// Build initial polygons.
int npolys = 0;
memset(polys, 0xff, maxVertsPerCont*nvp*sizeof(unsigned short));
@ -1096,7 +1182,9 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
unsigned short* pa = &polys[bestPa*nvp];
unsigned short* pb = &polys[bestPb*nvp];
mergePolys(pa, pb, bestEa, bestEb, tmpPoly, nvp);
memcpy(pb, &polys[(npolys-1)*nvp], sizeof(unsigned short)*nvp);
unsigned short* lastPoly = &polys[(npolys-1)*nvp];
if (pb != lastPoly)
memcpy(pb, lastPoly, sizeof(unsigned short)*nvp);
npolys--;
}
else
@ -1141,6 +1229,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
}
// Remove vertex
// Note: mesh.nverts is already decremented inside removeVertex()!
// Fixup vertex flags
for (int j = i; j < mesh.nverts; ++j)
vflags[j] = vflags[j+1];
--i;
@ -1153,6 +1242,37 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Adjacency failed.");
return false;
}
// Find portal edges
if (mesh.borderSize > 0)
{
const int w = cset.width;
const int h = cset.height;
for (int i = 0; i < mesh.npolys; ++i)
{
unsigned short* p = &mesh.polys[i*2*nvp];
for (int j = 0; j < nvp; ++j)
{
if (p[j] == RC_MESH_NULL_IDX) break;
// Skip connected edges.
if (p[nvp+j] != RC_MESH_NULL_IDX)
continue;
int nj = j+1;
if (nj >= nvp || p[nj] == RC_MESH_NULL_IDX) nj = 0;
const unsigned short* va = &mesh.verts[p[j]*3];
const unsigned short* vb = &mesh.verts[p[nj]*3];
if ((int)va[0] == 0 && (int)vb[0] == 0)
p[nvp+j] = 0x8000 | 0;
else if ((int)va[2] == h && (int)vb[2] == h)
p[nvp+j] = 0x8000 | 1;
else if ((int)va[0] == w && (int)vb[0] == w)
p[nvp+j] = 0x8000 | 2;
else if ((int)va[2] == 0 && (int)vb[2] == 0)
p[nvp+j] = 0x8000 | 3;
}
}
}
// Just allocate the mesh flags array. The user is resposible to fill it.
mesh.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*mesh.npolys, RC_ALLOC_PERM);
@ -1165,11 +1285,11 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
if (mesh.nverts > 0xffff)
{
ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff);
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff);
}
if (mesh.npolys > 0xffff)
{
ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
}
ctx->stopTimer(RC_TIMER_BUILD_POLYMESH);
@ -1177,6 +1297,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
return true;
}
/// @see rcAllocPolyMesh, rcPolyMesh
bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh)
{
rcAssert(ctx);
@ -1268,7 +1389,7 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'vremap' (%d).", maxVertsPerMesh);
return false;
}
memset(nextVert, 0, sizeof(int)*maxVerts);
memset(vremap, 0, sizeof(unsigned short)*maxVertsPerMesh);
for (int i = 0; i < nmeshes; ++i)
{
@ -1277,6 +1398,12 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f);
const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f);
bool isMinX = (ox == 0);
bool isMinZ = (oz == 0);
bool isMaxX = ((unsigned short)floorf((mesh.bmax[0] - pmesh->bmax[0]) / mesh.cs + 0.5f)) == 0;
bool isMaxZ = ((unsigned short)floorf((mesh.bmax[2] - pmesh->bmax[2]) / mesh.cs + 0.5f)) == 0;
bool isOnBorder = (isMinX || isMinZ || isMaxX || isMaxZ);
for (int j = 0; j < pmesh->nverts; ++j)
{
unsigned short* v = &pmesh->verts[j*3];
@ -1297,6 +1424,36 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
if (src[k] == RC_MESH_NULL_IDX) break;
tgt[k] = vremap[src[k]];
}
if (isOnBorder)
{
for (int k = mesh.nvp; k < mesh.nvp * 2; ++k)
{
if (src[k] & 0x8000 && src[k] != 0xffff)
{
unsigned short dir = src[k] & 0xf;
switch (dir)
{
case 0: // Portal x-
if (isMinX)
tgt[k] = src[k];
break;
case 1: // Portal z+
if (isMaxZ)
tgt[k] = src[k];
break;
case 2: // Portal x+
if (isMaxX)
tgt[k] = src[k];
break;
case 3: // Portal z-
if (isMinZ)
tgt[k] = src[k];
break;
}
}
}
}
}
}
@ -1320,3 +1477,67 @@ bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, r
return true;
}
bool rcCopyPolyMesh(rcContext* ctx, const rcPolyMesh& src, rcPolyMesh& dst)
{
rcAssert(ctx);
// Destination must be empty.
rcAssert(dst.verts == 0);
rcAssert(dst.polys == 0);
rcAssert(dst.regs == 0);
rcAssert(dst.areas == 0);
rcAssert(dst.flags == 0);
dst.nverts = src.nverts;
dst.npolys = src.npolys;
dst.maxpolys = src.npolys;
dst.nvp = src.nvp;
rcVcopy(dst.bmin, src.bmin);
rcVcopy(dst.bmax, src.bmax);
dst.cs = src.cs;
dst.ch = src.ch;
dst.borderSize = src.borderSize;
dst.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.nverts*3, RC_ALLOC_PERM);
if (!dst.verts)
{
ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.verts' (%d).", src.nverts*3);
return false;
}
memcpy(dst.verts, src.verts, sizeof(unsigned short)*src.nverts*3);
dst.polys = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.npolys*2*src.nvp, RC_ALLOC_PERM);
if (!dst.polys)
{
ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.polys' (%d).", src.npolys*2*src.nvp);
return false;
}
memcpy(dst.polys, src.polys, sizeof(unsigned short)*src.npolys*2*src.nvp);
dst.regs = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.npolys, RC_ALLOC_PERM);
if (!dst.regs)
{
ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.regs' (%d).", src.npolys);
return false;
}
memcpy(dst.regs, src.regs, sizeof(unsigned short)*src.npolys);
dst.areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*src.npolys, RC_ALLOC_PERM);
if (!dst.areas)
{
ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.areas' (%d).", src.npolys);
return false;
}
memcpy(dst.areas, src.areas, sizeof(unsigned char)*src.npolys);
dst.flags = (unsigned short*)rcAlloc(sizeof(unsigned short)*src.npolys, RC_ALLOC_PERM);
if (!dst.flags)
{
ctx->log(RC_LOG_ERROR, "rcCopyPolyMesh: Out of memory 'dst.flags' (%d).", src.npolys);
return false;
}
memcpy(dst.flags, src.flags, sizeof(unsigned short)*src.npolys);
return true;
}