This commit is contained in:
aozhiwei 2022-07-11 17:36:52 +08:00
parent 3390412e54
commit 6107ce973e

View File

@ -48,118 +48,127 @@ static void calcExtends(const BoundsItem* items, const int /*nitems*/,
bmax[0] = items[imin].bmax[0]; bmax[0] = items[imin].bmax[0];
bmax[1] = items[imin].bmax[1]; bmax[1] = items[imin].bmax[1];
for (int i = imin+1; i < imax; ++i) for (int i = imin+1; i < imax; ++i) {
{ const BoundsItem& it = items[i];
const BoundsItem& it = items[i]; if (it.bmin[0] < bmin[0]) bmin[0] = it.bmin[0];
if (it.bmin[0] < bmin[0]) bmin[0] = it.bmin[0]; if (it.bmin[1] < bmin[1]) bmin[1] = it.bmin[1];
if (it.bmin[1] < bmin[1]) bmin[1] = it.bmin[1];
if (it.bmax[0] > bmax[0]) bmax[0] = it.bmax[0]; if (it.bmax[0] > bmax[0]) bmax[0] = it.bmax[0];
if (it.bmax[1] > bmax[1]) bmax[1] = it.bmax[1]; if (it.bmax[1] > bmax[1]) bmax[1] = it.bmax[1];
} }
} }
static void subdivide(BoundsItem* items, int nitems, int imin, int imax, int trisPerChunk, static void subdivide(BoundsItem* items,
int& curNode, rcChunkyTriMeshNode* nodes, const int maxNodes, int nitems,
int& curTri, int* outTris, const int* inTris) int imin,
int imax,
int trisPerChunk,
int& curNode,
rcChunkyTriMeshNode* nodes,
const int maxNodes,
int& curTri,
int* outTris,
const int* inTris)
{ {
int inum = imax - imin; int inum = imax - imin;
int icur = curNode; int icur = curNode;
if (curNode > maxNodes) if (curNode > maxNodes) {
abort();
return; return;
}
rcChunkyTriMeshNode& node = nodes[curNode++]; rcChunkyTriMeshNode& node = nodes[curNode++];
if (inum <= trisPerChunk) if (inum <= trisPerChunk) {
{ // Leaf
// Leaf calcExtends(items, nitems, imin, imax, node.bmin, node.bmax);
calcExtends(items, nitems, imin, imax, node.bmin, node.bmax);
// Copy triangles. // Copy triangles.
node.i = curTri; node.i = curTri;
node.n = inum; node.n = inum;
for (int i = imin; i < imax; ++i) for (int i = imin; i < imax; ++i) {
{ const int* src = &inTris[items[i].i*3];
const int* src = &inTris[items[i].i*3]; int* dst = &outTris[curTri*3];
int* dst = &outTris[curTri*3]; curTri++;
curTri++; dst[0] = src[0];
dst[0] = src[0]; dst[1] = src[1];
dst[1] = src[1]; dst[2] = src[2];
dst[2] = src[2]; }
} } else {
} // Split
else calcExtends(items, nitems, imin, imax, node.bmin, node.bmax);
{
// Split
calcExtends(items, nitems, imin, imax, node.bmin, node.bmax);
int axis = longestAxis(node.bmax[0] - node.bmin[0], int axis = longestAxis(node.bmax[0] - node.bmin[0],
node.bmax[1] - node.bmin[1]); node.bmax[1] - node.bmin[1]);
if (axis == 0) if (axis == 0) {
{ // Sort along x-axis
// Sort along x-axis qsort(items+imin, static_cast<size_t>(inum), sizeof(BoundsItem), compareItemX);
qsort(items+imin, static_cast<size_t>(inum), sizeof(BoundsItem), compareItemX); } else if (axis == 1) {
} // Sort along y-axis
else if (axis == 1) qsort(items+imin, static_cast<size_t>(inum), sizeof(BoundsItem), compareItemY);
{ }
// Sort along y-axis
qsort(items+imin, static_cast<size_t>(inum), sizeof(BoundsItem), compareItemY);
}
int isplit = imin+inum/2; int isplit = imin+inum/2;
// Left // Left
subdivide(items, nitems, imin, isplit, trisPerChunk, curNode, nodes, maxNodes, curTri, outTris, inTris); subdivide(items, nitems, imin, isplit, trisPerChunk, curNode, nodes, maxNodes, curTri, outTris, inTris);
// Right // Right
subdivide(items, nitems, isplit, imax, trisPerChunk, curNode, nodes, maxNodes, curTri, outTris, inTris); subdivide(items, nitems, isplit, imax, trisPerChunk, curNode, nodes, maxNodes, curTri, outTris, inTris);
int iescape = curNode - icur; int iescape = curNode - icur;
// Negative index means escape. // Negative index means escape.
node.i = -iescape; node.i = -iescape;
} }
} }
bool rcCreateChunkyTriMesh(const float* verts, const int* tris, int ntris, static bool rcCreateChunkyTriMesh(const float* verts,
int trisPerChunk, rcChunkyTriMesh* cm) const int* tris,
int ntris,
int trisPerChunk,
rcChunkyTriMesh* cm)
{ {
int nchunks = (ntris + trisPerChunk-1) / trisPerChunk; int nchunks = (ntris + trisPerChunk-1) / trisPerChunk;
cm->nodes = new rcChunkyTriMeshNode[nchunks*4]; cm->nodes = new rcChunkyTriMeshNode[nchunks*4];
if (!cm->nodes) if (!cm->nodes) {
abort();
return false; return false;
}
cm->tris = new int[ntris*3]; cm->tris = new int[ntris*3];
if (!cm->tris) if (!cm->tris) {
abort();
return false; return false;
}
cm->ntris = ntris; cm->ntris = ntris;
// Build tree // Build tree
BoundsItem* items = new BoundsItem[ntris]; BoundsItem* items = new BoundsItem[ntris];
if (!items) if (!items) {
abort();
return false; return false;
}
for (int i = 0; i < ntris; i++) for (int i = 0; i < ntris; i++) {
{ const int* t = &tris[i*3];
const int* t = &tris[i*3]; BoundsItem& it = items[i];
BoundsItem& it = items[i]; it.i = i;
it.i = i; // Calc triangle XZ bounds.
// Calc triangle XZ bounds. it.bmin[0] = it.bmax[0] = verts[t[0]*3+0];
it.bmin[0] = it.bmax[0] = verts[t[0]*3+0]; it.bmin[1] = it.bmax[1] = verts[t[0]*3+2];
it.bmin[1] = it.bmax[1] = verts[t[0]*3+2]; for (int j = 1; j < 3; ++j) {
for (int j = 1; j < 3; ++j) const float* v = &verts[t[j]*3];
{ if (v[0] < it.bmin[0]) it.bmin[0] = v[0];
const float* v = &verts[t[j]*3]; if (v[2] < it.bmin[1]) it.bmin[1] = v[2];
if (v[0] < it.bmin[0]) it.bmin[0] = v[0];
if (v[2] < it.bmin[1]) it.bmin[1] = v[2];
if (v[0] > it.bmax[0]) it.bmax[0] = v[0]; if (v[0] > it.bmax[0]) it.bmax[0] = v[0];
if (v[2] > it.bmax[1]) it.bmax[1] = v[2]; if (v[2] > it.bmax[1]) it.bmax[1] = v[2];
} }
} }
int curTri = 0; int curTri = 0;
int curNode = 0; int curNode = 0;
@ -171,14 +180,14 @@ bool rcCreateChunkyTriMesh(const float* verts, const int* tris, int ntris,
// Calc max tris per node. // Calc max tris per node.
cm->maxTrisPerChunk = 0; cm->maxTrisPerChunk = 0;
for (int i = 0; i < cm->nnodes; ++i) for (int i = 0; i < cm->nnodes; ++i) {
{ rcChunkyTriMeshNode& node = cm->nodes[i];
rcChunkyTriMeshNode& node = cm->nodes[i]; const bool isLeaf = node.i >= 0;
const bool isLeaf = node.i >= 0; if (!isLeaf) continue;
if (!isLeaf) continue; if (node.n > cm->maxTrisPerChunk) {
if (node.n > cm->maxTrisPerChunk) cm->maxTrisPerChunk = node.n;
cm->maxTrisPerChunk = node.n; }
} }
return true; return true;
} }
@ -235,11 +244,11 @@ namespace f8
verts_.push_back(0); verts_.push_back(0);
verts_.push_back(0); verts_.push_back(0);
verts_.push_back(height); verts_.push_back(-height);
verts_.push_back(width); verts_.push_back(width);
verts_.push_back(0); verts_.push_back(0);
verts_.push_back(height); verts_.push_back(-height);
verts_.push_back(width); verts_.push_back(width);
verts_.push_back(0); verts_.push_back(0);