[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

@ -56,7 +56,7 @@ inline float vdist2(const float* p, const float* q)
}
inline float vcross2(const float* p1, const float* p2, const float* p3)
{
{
const float u1 = p2[0] - p1[0];
const float v1 = p2[2] - p1[2];
const float u2 = p3[0] - p1[0];
@ -68,21 +68,27 @@ static bool circumCircle(const float* p1, const float* p2, const float* p3,
float* c, float& r)
{
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)
{
const float p1Sq = vdot2(p1,p1);
const float p2Sq = vdot2(p2,p2);
const float p3Sq = vdot2(p3,p3);
c[0] = (p1Sq*(p2[2]-p3[2]) + p2Sq*(p3[2]-p1[2]) + p3Sq*(p1[2]-p2[2])) / (2*cp);
c[2] = (p1Sq*(p3[0]-p2[0]) + p2Sq*(p1[0]-p3[0]) + p3Sq*(p2[0]-p1[0])) / (2*cp);
r = vdist2(c, p1);
const float v1Sq = vdot2(v1,v1);
const float v2Sq = vdot2(v2,v2);
const float v3Sq = vdot2(v3,v3);
c[0] = (v1Sq*(v2[2]-v3[2]) + v2Sq*(v3[2]-v1[2]) + v3Sq*(v1[2]-v2[2])) / (2*cp);
c[1] = 0;
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;
}
c[0] = p1[0];
c[2] = p1[2];
rcVcopy(c, p1);
r = 0;
return false;
}
@ -93,7 +99,7 @@ static float distPtTri(const float* p, const float* a, const float* b, const flo
rcVsub(v0, c,a);
rcVsub(v1, b,a);
rcVsub(v2, p,a);
const float dot00 = vdot2(v0, v0);
const float dot01 = vdot2(v0, v1);
const float dot02 = vdot2(v0, v2);
@ -178,7 +184,7 @@ static float distToTriMesh(const float* p, const float* verts, const int /*nvert
static float distToPoly(int nvert, const float* verts, const float* p)
{
float dmin = FLT_MAX;
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++)
@ -200,8 +206,8 @@ static unsigned short getHeight(const float fx, const float fy, const float fz,
{
int ix = (int)floorf(fx*ics + 0.01f);
int iz = (int)floorf(fz*ics + 0.01f);
ix = rcClamp(ix-hp.xmin, 0, hp.width);
iz = rcClamp(iz-hp.ymin, 0, hp.height);
ix = rcClamp(ix-hp.xmin, 0, hp.width - 1);
iz = rcClamp(iz-hp.ymin, 0, hp.height - 1);
unsigned short h = hp.data[ix+iz*hp.width];
if (h == RC_UNSET_HEIGHT)
{
@ -216,22 +222,13 @@ static unsigned short getHeight(const float fx, const float fy, const float fz,
if (nx < 0 || nz < 0 || nx >= hp.width || nz >= hp.height) continue;
const unsigned short nh = hp.data[nx+nz*hp.width];
if (nh == RC_UNSET_HEIGHT) continue;
const float d = fabsf(nh*ch - fy);
if (d < dmin)
{
h = nh;
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;
@ -263,15 +260,15 @@ static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges,
return UNDEF;
}
// Add edge if not already in the triangulation.
// Add edge if not already in the triangulation.
int e = findEdge(edges, nedges, s, t);
if (e == UNDEF)
{
int* e = &edges[nedges*4];
e[0] = s;
e[1] = t;
e[2] = l;
e[3] = r;
int* edge = &edges[nedges*4];
edge[0] = s;
edge[1] = t;
edge[2] = l;
edge[3] = r;
return nedges++;
}
else
@ -286,7 +283,7 @@ static void updateLeftFace(int* e, int s, int t, int f)
e[2] = f;
else if (e[1] == s && e[0] == t && e[3] == UNDEF)
e[3] = f;
}
}
static int overlapSegSeg2d(const float* a, const float* b, const float* c, const float* d)
{
@ -298,7 +295,7 @@ static int overlapSegSeg2d(const float* a, const float* b, const float* c, const
float a4 = a3 + a2 - a1;
if (a3 * a4 < 0.0f)
return 1;
}
}
return 0;
}
@ -320,7 +317,7 @@ static bool overlapEdges(const float* pts, const int* edges, int nedges, int s1,
static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges, int& nedges, const int maxEdges, int& nfaces, int e)
{
static const float EPS = 1e-5f;
int* edge = &edges[e*4];
// Cache s and t.
@ -337,11 +334,11 @@ static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges
}
else
{
// Edge already completed.
// Edge already completed.
return;
}
// Find best point on left of edge.
// Find best point on left of edge.
int pt = npts;
float c[3] = {0,0,0};
float r = -1;
@ -385,20 +382,20 @@ static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges
}
}
// Add new triangle or update edge info if s-t is on hull.
// Add new triangle or update edge info if s-t is on hull.
if (pt < npts)
{
// Update face information of edge being completed.
// Update face information of edge being completed.
updateLeftFace(&edges[e*4], s, t, nfaces);
// Add new edge or update face info of old edge.
// Add new edge or update face info of old edge.
e = findEdge(edges, nedges, pt, s);
if (e == UNDEF)
addEdge(ctx, edges, nedges, maxEdges, pt, s, nfaces, UNDEF);
else
updateLeftFace(&edges[e*4], pt, s, nfaces);
// Add new edge or update face info of old edge.
// Add new edge or update face info of old edge.
e = findEdge(edges, nedges, t, pt);
if (e == UNDEF)
addEdge(ctx, edges, nedges, maxEdges, t, pt, nfaces, UNDEF);
@ -434,7 +431,7 @@ static void delaunayHull(rcContext* ctx, const int npts, const float* pts,
completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);
currentEdge++;
}
// Create tris
tris.resize(nfaces*4);
for (int i = 0; i < nfaces*4; ++i)
@ -489,6 +486,103 @@ static void delaunayHull(rcContext* ctx, const int npts, const float* pts,
}
}
// Calculate minimum extend of the polygon.
static float polyMinExtent(const float* verts, const int nverts)
{
float minDist = FLT_MAX;
for (int i = 0; i < nverts; i++)
{
const int ni = (i+1) % nverts;
const float* p1 = &verts[i*3];
const float* p2 = &verts[ni*3];
float maxEdgeDist = 0;
for (int j = 0; j < nverts; j++)
{
if (j == i || j == ni) continue;
float d = distancePtSeg2d(&verts[j*3], p1,p2);
maxEdgeDist = rcMax(maxEdgeDist, d);
}
minDist = rcMin(minDist, maxEdgeDist);
}
return rcSqrt(minDist);
}
inline int next(int i, int n)
{
return (i+1) % n;
}
inline int prev(int i, int n)
{
return (i + n-1) % n;
}
static void triangulateHull(const int nverts, const float* verts, const int nhull, const int* hull, rcIntArray& tris)
{
int start = 0, left = 1, right = nhull-1;
// Start from an ear with shortest perimeter.
// This tends to favor well formed triangles as starting point.
float dmin = 0;
for (int i = 0; i < nhull; i++)
{
int pi = prev(i, nhull);
int ni = next(i, nhull);
const float* pv = &verts[hull[pi]*3];
const float* cv = &verts[hull[i]*3];
const float* nv = &verts[hull[ni]*3];
const float d = vdist2(pv,cv) + vdist2(cv,nv) + vdist2(nv,pv);
if (d < dmin)
{
start = i;
left = ni;
right = pi;
dmin = d;
}
}
// Add first triangle
tris.push(hull[start]);
tris.push(hull[left]);
tris.push(hull[right]);
tris.push(0);
// Triangulate the polygon 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)
{
// Check to see if se should advance left or right.
int nleft = next(left, nhull);
int nright = prev(right, nhull);
const float* cvleft = &verts[hull[left]*3];
const float* nvleft = &verts[hull[nleft]*3];
const float* cvright = &verts[hull[right]*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);
if (dleft < dright)
{
tris.push(hull[left]);
tris.push(hull[nleft]);
tris.push(hull[right]);
tris.push(0);
left = nleft;
}
else
{
tris.push(hull[left]);
tris.push(hull[nright]);
tris.push(hull[right]);
tris.push(0);
right = nright;
}
}
}
inline float getJitterX(const int i)
{
@ -512,16 +606,22 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
float edge[(MAX_VERTS_PER_EDGE+1)*3];
int hull[MAX_VERTS];
int nhull = 0;
nverts = 0;
for (int i = 0; i < nin; ++i)
rcVcopy(&verts[i*3], &in[i*3]);
nverts = nin;
edges.resize(0);
tris.resize(0);
const float cs = chf.cs;
const float ics = 1.0f/cs;
// Calculate minimum extents of the polygon based on input data.
float minExtent = polyMinExtent(verts, nverts);
// Tessellate outlines.
// This is done in separate pass in order to ensure
// seamless height values across the ply boundaries.
@ -583,10 +683,10 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
int maxi = -1;
for (int m = a+1; m < b; ++m)
{
float d = distancePtSeg(&edge[m*3],va,vb);
if (d > maxd)
float dev = distancePtSeg(&edge[m*3],va,vb);
if (dev > maxd)
{
maxd = d;
maxd = dev;
maxi = m;
}
}
@ -628,27 +728,26 @@ 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 (minExtent < sampleDist*2)
{
triangulateHull(nverts, verts, nhull, hull, tris);
return true;
}
// Tessellate the base mesh.
edges.resize(0);
tris.resize(0);
delaunayHull(ctx, nverts, verts, nhull, hull, tris, edges);
// We're using the triangulateHull instead of delaunayHull as it tends to
// create a bit better triangulation for long thing triangles when there
// are no internal points.
triangulateHull(nverts, verts, nhull, hull, tris);
if (tris.size() == 0)
{
// Could not triangulate the poly, make sure there is some valid data there.
ctx->log(RC_LOG_WARNING, "buildPolyDetail: Could not triangulate polygon, adding default data.");
for (int i = 2; i < nverts; ++i)
{
tris.push(0);
tris.push(i-1);
tris.push(i);
tris.push(0);
}
ctx->log(RC_LOG_WARNING, "buildPolyDetail: Could not triangulate polygon (%d verts).", nverts);
return true;
}
if (sampleDist > 0)
{
// Create sample locations in a grid.
@ -681,7 +780,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
samples.push(0); // Not added
}
}
// Add the samples starting from the one that has the most
// error. The procedure stops when all samples are added
// or when the max error is within treshold.
@ -690,7 +789,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
{
if (nverts >= MAX_VERTS)
break;
// Find sample with most error.
float bestpt[3] = {0,0,0};
float bestd = 0;
@ -728,27 +827,31 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
edges.resize(0);
tris.resize(0);
delaunayHull(ctx, nverts, verts, nhull, hull, tris, edges);
}
}
}
const int ntris = tris.size()/4;
if (ntris > MAX_TRIS)
{
tris.resize(MAX_TRIS*4);
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Shrinking triangle count from %d to max %d.", ntris, MAX_TRIS);
}
return true;
}
static void getHeightData(const rcCompactHeightfield& chf,
const unsigned short* poly, const int npoly,
const unsigned short* verts,
rcHeightPatch& hp, rcIntArray& stack)
static void getHeightDataSeedsFromVertices(const rcCompactHeightfield& chf,
const unsigned short* poly, const int npoly,
const unsigned short* verts, const int bs,
rcHeightPatch& hp, rcIntArray& stack)
{
// Floodfill the heightfield to get 2D height data,
// starting at vertex locations as seeds.
// Note: Reads to the compact heightfield are offset by border size (bs)
// since border size offset is already removed from the polymesh vertices.
memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height);
stack.resize(0);
@ -772,7 +875,7 @@ static void getHeightData(const rcCompactHeightfield& chf,
az < hp.ymin || az >= hp.ymin+hp.height)
continue;
const rcCompactCell& c = chf.cells[ax+az*chf.width];
const rcCompactCell& c = chf.cells[(ax+bs)+(az+bs)*chf.width];
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
{
const rcCompactSpan& s = chf.spans[i];
@ -844,8 +947,8 @@ static void getHeightData(const rcCompactHeightfield& chf,
if (hp.data[ax-hp.xmin+(ay-hp.ymin)*hp.width] != 0)
continue;
const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(cs, dir);
const int ai = (int)chf.cells[(ax+bs)+(ay+bs)*chf.width].index + rcGetCon(cs, dir);
int idx = ax-hp.xmin+(ay-hp.ymin)*hp.width;
hp.data[idx] = 1;
@ -854,9 +957,9 @@ static void getHeightData(const rcCompactHeightfield& chf,
stack.push(ai);
}
}
memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);
// Mark start locations.
for (int i = 0; i < stack.size(); i += 3)
{
@ -866,8 +969,83 @@ static void getHeightData(const rcCompactHeightfield& chf,
int idx = cx-hp.xmin+(cy-hp.ymin)*hp.width;
const rcCompactSpan& cs = chf.spans[ci];
hp.data[idx] = cs.y;
// getHeightData seeds are given in coordinates with borders
stack[i+0] += bs;
stack[i+1] += bs;
}
}
static void getHeightData(const rcCompactHeightfield& chf,
const unsigned short* poly, const int npoly,
const unsigned short* verts, const int bs,
rcHeightPatch& hp, rcIntArray& stack,
int region)
{
// Note: Reads to the compact heightfield are offset by border size (bs)
// since border size offset is already removed from the polymesh vertices.
stack.resize(0);
memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);
bool empty = true;
// Copy the height from the same region, and mark region borders
// as seed points to fill the rest.
for (int hy = 0; hy < hp.height; hy++)
{
int y = hp.ymin + hy + bs;
for (int hx = 0; hx < hp.width; hx++)
{
int x = hp.xmin + hx + bs;
const rcCompactCell& c = chf.cells[x+y*chf.width];
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
{
const rcCompactSpan& s = chf.spans[i];
if (s.reg == region)
{
// Store height
hp.data[hx + hy*hp.width] = s.y;
empty = false;
// If any of the neighbours is not in same region,
// add the current location as flood fill start
bool border = false;
for (int dir = 0; dir < 4; ++dir)
{
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
{
const int ax = x + rcGetDirOffsetX(dir);
const int ay = y + rcGetDirOffsetY(dir);
const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir);
const rcCompactSpan& as = chf.spans[ai];
if (as.reg != region)
{
border = true;
break;
}
}
}
if (border)
{
stack.push(x);
stack.push(y);
stack.push(i);
}
break;
}
}
}
}
// if the polygon does not contian any points from the current region (rare, but happens)
// then use the cells closest to the polygon vertices as seeds to fill the height field
if (empty)
getHeightDataSeedsFromVertices(chf, poly, npoly, verts, bs, hp, stack);
static const int RETRACT_SIZE = 256;
int head = 0;
@ -884,7 +1062,7 @@ static void getHeightData(const rcCompactHeightfield& chf,
memmove(&stack[0], &stack[RETRACT_SIZE*3], sizeof(int)*(stack.size()-RETRACT_SIZE*3));
stack.resize(stack.size()-RETRACT_SIZE*3);
}
const rcCompactSpan& cs = chf.spans[ci];
for (int dir = 0; dir < 4; ++dir)
{
@ -892,26 +1070,25 @@ static void getHeightData(const rcCompactHeightfield& chf,
const int ax = cx + rcGetDirOffsetX(dir);
const int ay = cy + rcGetDirOffsetY(dir);
const int hx = ax - hp.xmin - bs;
const int hy = ay - hp.ymin - bs;
if (ax < hp.xmin || ax >= (hp.xmin+hp.width) ||
ay < hp.ymin || ay >= (hp.ymin+hp.height))
if (hx < 0 || hx >= hp.width || hy < 0 || hy >= hp.height)
continue;
if (hp.data[ax-hp.xmin+(ay-hp.ymin)*hp.width] != RC_UNSET_HEIGHT)
if (hp.data[hx + hy*hp.width] != RC_UNSET_HEIGHT)
continue;
const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(cs, dir);
const int ai = (int)chf.cells[ax + ay*chf.width].index + rcGetCon(cs, dir);
const rcCompactSpan& as = chf.spans[ai];
int idx = ax-hp.xmin+(ay-hp.ymin)*hp.width;
hp.data[idx] = as.y;
hp.data[hx + hy*hp.width] = as.y;
stack.push(ax);
stack.push(ay);
stack.push(ai);
}
}
}
static unsigned char getEdgeFlags(const float* va, const float* vb,
@ -921,7 +1098,7 @@ static unsigned char getEdgeFlags(const float* va, const float* vb,
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 &&
if (distancePtSeg2d(va, &vpoly[j*3], &vpoly[i*3]) < thrSqr &&
distancePtSeg2d(vb, &vpoly[j*3], &vpoly[i*3]) < thrSqr)
return 1;
}
@ -938,8 +1115,11 @@ static unsigned char getTriFlags(const float* va, const float* vb, const float*
return flags;
}
/// @par
///
/// See the #rcConfig documentation for more information on the configuration parameters.
///
/// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig
bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
const float sampleDist, const float sampleMaxError,
rcPolyMeshDetail& dmesh)
@ -947,7 +1127,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
rcAssert(ctx);
ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
if (mesh.nverts == 0 || mesh.npolys == 0)
return true;
@ -955,6 +1135,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
const float cs = mesh.cs;
const float ch = mesh.ch;
const float* orig = mesh.bmin;
const int borderSize = mesh.borderSize;
rcIntArray edges(64);
rcIntArray tris(512);
@ -1025,10 +1206,10 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4);
return false;
}
int vcap = nPolyVerts+nPolyVerts/2;
int tcap = vcap*2;
dmesh.nverts = 0;
dmesh.verts = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM);
if (!dmesh.verts)
@ -1037,7 +1218,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
return false;
}
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)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4);
@ -1065,7 +1246,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
hp.ymin = bounds[i*4+2];
hp.width = bounds[i*4+1]-bounds[i*4+0];
hp.height = bounds[i*4+3]-bounds[i*4+2];
getHeightData(chf, p, npoly, mesh.verts, hp, stack);
getHeightData(chf, p, npoly, mesh.verts, borderSize, hp, stack, mesh.regs[i]);
// Build detail mesh.
int nverts = 0;
@ -1076,7 +1257,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
{
return false;
}
// Move detail verts to world space.
for (int j = 0; j < nverts; ++j)
{
@ -1091,21 +1272,21 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
poly[j*3+1] += orig[1];
poly[j*3+2] += orig[2];
}
// Store detail submesh.
const int ntris = tris.size()/4;
dmesh.meshes[i*4+0] = (unsigned int)dmesh.nverts;
dmesh.meshes[i*4+1] = (unsigned int)nverts;
dmesh.meshes[i*4+2] = (unsigned int)dmesh.ntris;
dmesh.meshes[i*4+3] = (unsigned int)ntris;
dmesh.meshes[i*4+3] = (unsigned int)ntris;
// Store vertices, allocate more memory if necessary.
if (dmesh.nverts+nverts > vcap)
{
while (dmesh.nverts+nverts > vcap)
vcap += 256;
float* newv = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM);
if (!newv)
{
@ -1151,22 +1332,23 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
dmesh.ntris++;
}
}
ctx->stopTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
return true;
}
/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail
bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh)
{
rcAssert(ctx);
ctx->startTimer(RC_TIMER_MERGE_POLYMESHDETAIL);
int maxVerts = 0;
int maxTris = 0;
int maxMeshes = 0;
for (int i = 0; i < nmeshes; ++i)
{
if (!meshes[i]) continue;
@ -1174,7 +1356,7 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
maxTris += meshes[i]->ntris;
maxMeshes += meshes[i]->nmeshes;
}
mesh.nmeshes = 0;
mesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*maxMeshes*4, RC_ALLOC_PERM);
if (!mesh.meshes)
@ -1182,7 +1364,7 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'pmdtl.meshes' (%d).", maxMeshes*4);
return false;
}
mesh.ntris = 0;
mesh.tris = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxTris*4, RC_ALLOC_PERM);
if (!mesh.tris)
@ -1190,7 +1372,7 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", maxTris*4);
return false;
}
mesh.nverts = 0;
mesh.verts = (float*)rcAlloc(sizeof(float)*maxVerts*3, RC_ALLOC_PERM);
if (!mesh.verts)
@ -1214,7 +1396,7 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
dst[3] = src[3];
mesh.nmeshes++;
}
for (int k = 0; k < dm->nverts; ++k)
{
rcVcopy(&mesh.verts[mesh.nverts*3], &dm->verts[k*3]);
@ -1229,9 +1411,8 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
mesh.ntris++;
}
}
ctx->stopTimer(RC_TIMER_MERGE_POLYMESHDETAIL);
return true;
}