Improved return method for node indexes from partitioned mesh queries

This commit is contained in:
Graham Pentheny
2025-08-06 13:03:45 -04:00
parent 47f82a60cd
commit e79906ee48
5 changed files with 39 additions and 52 deletions

View File

@@ -43,8 +43,8 @@ struct PartitionedMesh
void PartitionMesh(const float* verts, const int* tris, int ntris, int trisPerChunk);
/// Finds the chunk indices that overlap the input rectangle.
int GetNodesOverlappingRect(float bmin[2], float bmax[2], int* ids, int maxIds) const;
void GetNodesOverlappingRect(float bmin[2], float bmax[2], std::vector<int>& outNodes) const;
/// Returns the chunk indices which overlap the input segment.
int GetNodesOverlappingSegment(float segmentStart[2], float segmentEnd[2], int* ids, int maxIds) const;
void GetNodesOverlappingSegment(float start[2], float end[2], std::vector<int>& outNodes) const;
};

View File

@@ -488,9 +488,9 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin)
float p[]{p[0] = src[0] + (dst[0] - src[0]) * btmin, p[1] = src[2] + (dst[2] - src[2]) * btmin};
float q[]{src[0] + (dst[0] - src[0]) * btmax, src[2] + (dst[2] - src[2]) * btmax};
int cid[512];
const int ncid = partitionedMesh->GetChunksOverlappingSegment(p, q, cid, 512);
if (!ncid)
std::vector<int> overlappingNodes;
partitionedMesh->GetNodesOverlappingSegment(p, q, overlappingNodes);
if (overlappingNodes.empty())
{
return false;
}
@@ -498,9 +498,9 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin)
tmin = 1.0f;
bool hit = false;
for (int i = 0; i < ncid; ++i)
for (int nodeIndex : overlappingNodes)
{
const PartitionedMesh::Node& node = partitionedMesh->nodes[cid[i]];
const PartitionedMesh::Node& node = partitionedMesh->nodes[nodeIndex];
const int* tris = &partitionedMesh->tris[node.triIndex * 3];
const int ntris = node.numTris;

View File

@@ -86,7 +86,7 @@ void subdivide(
PartitionedMesh::Node& node = nodes[curNode];
curNode++;
if (numTriBoundsInRange <= trisPerChunk) // Leaf
if (numTriBoundsInRange <= trisPerChunk) // Leaf
{
// Get total bounds of all triangles
calcTotalBounds(triBounds, imin, imax, node.bmin, node.bmax);
@@ -113,7 +113,11 @@ void subdivide(
float yLength = node.bmax[1] - node.bmin[1];
// Sort along the longest axis
qsort(triBounds.data() + imin, static_cast<size_t>(numTriBoundsInRange), sizeof(IndexedBounds), (xLength >= yLength) ? compareMinX : compareMinY);
qsort(
triBounds.data() + imin,
static_cast<size_t>(numTriBoundsInRange),
sizeof(IndexedBounds),
(xLength >= yLength) ? compareMinX : compareMinY);
int isplit = imin + numTriBoundsInRange / 2;
@@ -225,70 +229,54 @@ void PartitionedMesh::PartitionMesh(const float* verts, const int* tris, int num
}
}
int PartitionedMesh::GetChunksOverlappingRect(float bmin[2], float bmax[2], int* ids, const int maxIds) const
void PartitionedMesh::GetNodesOverlappingRect(float bmin[2], float bmax[2], std::vector<int>& outNodes) const
{
// Traverse tree
int i = 0;
int n = 0;
while (i < this->nnodes)
for (int nodeIndex = 0; nodeIndex < this->nnodes;)
{
const Node* node = &this->nodes[i];
const Node* node = &this->nodes[nodeIndex];
const bool overlap = checkOverlapRect(bmin, bmax, node->bmin, node->bmax);
const bool isLeafNode = node->triIndex >= 0;
if (isLeafNode && overlap)
{
if (n < maxIds)
{
ids[n] = i;
n++;
}
outNodes.emplace_back(nodeIndex);
}
if (overlap || isLeafNode)
{
i++;
nodeIndex++;
}
else
{
const int escapeIndex = -node->triIndex;
i += escapeIndex;
// escape index
nodeIndex -= node->triIndex;
}
}
return n;
}
int PartitionedMesh::GetChunksOverlappingSegment(float segmentStart[2], float segmentEnd[2], int* ids, const int maxIds) const
void PartitionedMesh::GetNodesOverlappingSegment(float start[2], float end[2], std::vector<int>& outNodes) const
{
// Traverse tree
int i = 0;
int n = 0;
while (i < this->nnodes)
for (int nodeIndex = 0; nodeIndex < this->nnodes;)
{
const Node* node = &this->nodes[i];
const bool overlap = checkOverlapSegment(segmentStart, segmentEnd, node->bmin, node->bmax);
const Node* node = &this->nodes[nodeIndex];
const bool overlap = checkOverlapSegment(start, end, node->bmin, node->bmax);
const bool isLeafNode = node->triIndex >= 0;
if (isLeafNode && overlap)
{
if (n < maxIds)
{
ids[n] = i;
n++;
}
outNodes.emplace_back(nodeIndex);
}
if (overlap || isLeafNode)
{
i++;
nodeIndex++;
}
else
{
const int escapeIndex = -node->triIndex;
i += escapeIndex;
// escape index
nodeIndex -= node->triIndex;
}
}
return n;
}

View File

@@ -597,16 +597,16 @@ int Sample_TempObstacles::rasterizeTileLayers(
tbmin[1] = tcfg.bmin[2];
tbmax[0] = tcfg.bmax[0];
tbmax[1] = tcfg.bmax[2];
int cid[512]; // TODO: Make grow when returning too many items.
const int ncid = partitionedMesh->GetChunksOverlappingRect(tbmin, tbmax, cid, 512);
if (!ncid)
std::vector<int> overlappingNodes;
partitionedMesh->GetNodesOverlappingRect(tbmin, tbmax, overlappingNodes);
if (overlappingNodes.empty())
{
return 0; // empty
return 0;
}
for (int i = 0; i < ncid; ++i)
for (int nodeIndex : overlappingNodes)
{
const PartitionedMesh::Node& node = partitionedMesh->nodes[cid[i]];
const PartitionedMesh::Node& node = partitionedMesh->nodes[nodeIndex];
const int* tris = &partitionedMesh->tris[node.triIndex * 3];
const int ntris = node.numTris;

View File

@@ -949,19 +949,18 @@ unsigned char* Sample_TileMesh::buildTileMesh(
tileBoundsMin[1] = config.bmin[2];
tileBoundsMax[0] = config.bmax[0];
tileBoundsMax[1] = config.bmax[2];
int overlappingChunkIndexes[512]; // TODO: Make grow when returning too many items.
const int numOverlappingChunks =
partitionedMesh->GetChunksOverlappingRect(tileBoundsMin, tileBoundsMax, overlappingChunkIndexes, 512);
if (!numOverlappingChunks)
std::vector<int> overlappingNodes;
partitionedMesh->GetNodesOverlappingRect(tileBoundsMin, tileBoundsMax, overlappingNodes);
if (overlappingNodes.empty())
{
return 0;
}
tileTriCount = 0;
for (int i = 0; i < numOverlappingChunks; ++i)
for (int nodeIndex : overlappingNodes)
{
const PartitionedMesh::Node& node = partitionedMesh->nodes[overlappingChunkIndexes[i]];
const PartitionedMesh::Node& node = partitionedMesh->nodes[nodeIndex];
const int* nodeTris = &partitionedMesh->tris[node.triIndex * 3];
const int numNodeTris = node.numTris;