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

View File

@ -48,8 +48,7 @@ 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];
@ -59,20 +58,29 @@ static void calcExtends(const BoundsItem* items, const int /*nitems*/,
} }
} }
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);
@ -80,8 +88,7 @@ static void subdivide(BoundsItem* items, int nitems, int imin, int imax, int tri
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++;
@ -89,22 +96,17 @@ static void subdivide(BoundsItem* items, int nitems, int imin, int imax, int tri
dst[1] = src[1]; dst[1] = src[1];
dst[2] = src[2]; dst[2] = src[2];
} }
} } else {
else
{
// Split // Split
calcExtends(items, nitems, imin, imax, node.bmin, node.bmax); 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) {
else if (axis == 1)
{
// Sort along y-axis // Sort along y-axis
qsort(items+imin, static_cast<size_t>(inum), sizeof(BoundsItem), compareItemY); qsort(items+imin, static_cast<size_t>(inum), sizeof(BoundsItem), compareItemY);
} }
@ -122,36 +124,43 @@ static void subdivide(BoundsItem* items, int nitems, int imin, int imax, int tri
} }
} }
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]; const float* v = &verts[t[j]*3];
if (v[0] < it.bmin[0]) it.bmin[0] = v[0]; if (v[0] < it.bmin[0]) it.bmin[0] = v[0];
if (v[2] < it.bmin[1]) it.bmin[1] = v[2]; if (v[2] < it.bmin[1]) it.bmin[1] = v[2];
@ -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);