mirror of
https://github.com/recastnavigation/recastnavigation.git
synced 2026-08-16 08:09:53 +00:00
Improved return method for node indexes from partitioned mesh queries
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user