mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 20:44:14 +02:00
make sure to exit early if box intersection is already larger than best triangle intersection
This commit is contained in:
parent
eb3b27849c
commit
89b6a79f68
2 changed files with 47 additions and 19 deletions
|
@ -33,13 +33,16 @@ void TriangleSet::clear() {
|
|||
bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal, bool precision) {
|
||||
|
||||
// reset our distance to be the max possible, lower level tests will store best distance here
|
||||
distance = std::numeric_limits<float>::max();
|
||||
|
||||
if (!_isBalanced) {
|
||||
balanceOctree();
|
||||
}
|
||||
|
||||
int trianglesTouched = 0;
|
||||
auto result = _triangleOctree.findRayIntersection(origin, direction, distance, face, surfaceNormal, precision, trianglesTouched);
|
||||
qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population;
|
||||
//qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -77,10 +80,9 @@ void TriangleSet::balanceOctree() {
|
|||
_triangleOctree.insert(i);
|
||||
}
|
||||
|
||||
// prune the empty cells
|
||||
_triangleOctree.prune();
|
||||
|
||||
_isBalanced = true;
|
||||
|
||||
//debugDump();
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,10 +108,17 @@ bool InternalTriangleSet::findRayIntersection(const glm::vec3& origin, const glm
|
|||
float& distance, BoxFace& face, glm::vec3& surfaceNormal, bool precision, int& trianglesTouched) {
|
||||
|
||||
bool intersectedSomething = false;
|
||||
float boxDistance = std::numeric_limits<float>::max();
|
||||
float bestDistance = std::numeric_limits<float>::max();
|
||||
float boxDistance = distance; // std::numeric_limits<float>::max();
|
||||
float bestDistance = distance; // std::numeric_limits<float>::max();
|
||||
|
||||
if (_bounds.findRayIntersection(origin, direction, boxDistance, face, surfaceNormal)) {
|
||||
|
||||
// if our bounding box intersects at a distance greater than the current known
|
||||
// best distance, than we can safely not check any of our triangles
|
||||
if (boxDistance > bestDistance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (precision) {
|
||||
for (const auto& triangleIndex : _triangleIndices) {
|
||||
const auto& triangle = _allTriangles[triangleIndex];
|
||||
|
@ -148,10 +157,6 @@ void TriangleOctreeCell::clear() {
|
|||
_population = 0;
|
||||
}
|
||||
|
||||
void TriangleOctreeCell::prune() {
|
||||
// do nothing yet...
|
||||
}
|
||||
|
||||
void TriangleOctreeCell::reset(const AABox& bounds, int depth) {
|
||||
clear();
|
||||
_triangleSet._bounds = bounds;
|
||||
|
@ -159,10 +164,6 @@ void TriangleOctreeCell::reset(const AABox& bounds, int depth) {
|
|||
if (depth <= MAX_DEPTH) {
|
||||
int childDepth = depth + 1;
|
||||
_children.clear();
|
||||
for (int child = 0; child < MAX_CHILDREN; child++) {
|
||||
AABox childBounds = getBounds().getOctreeChild((AABox::OctreeChild)child);
|
||||
_children.push_back(TriangleOctreeCell(_allTriangles, childBounds, childDepth));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,8 +171,9 @@ void TriangleOctreeCell::debugDump() {
|
|||
qDebug() << __FUNCTION__;
|
||||
qDebug() << "bounds:" << getBounds();
|
||||
qDebug() << "depth:" << _depth;
|
||||
//qDebug() << "triangleSet:" << _triangleSet.size() << "at this level";
|
||||
qDebug() << "population:" << _population << "this level or below";
|
||||
qDebug() << "triangleSet:" << _triangleSet.size() << "in this cell";
|
||||
qDebug() << "child cells:" << _children.size();
|
||||
if (_depth < MAX_DEPTH) {
|
||||
int childNum = 0;
|
||||
for (auto& child : _children) {
|
||||
|
@ -187,12 +189,30 @@ void TriangleOctreeCell::insert(int triangleIndex) {
|
|||
_population++;
|
||||
// if we're not yet at the max depth, then check which child the triangle fits in
|
||||
if (_depth < MAX_DEPTH) {
|
||||
|
||||
// check existing children to see if this triangle fits them...
|
||||
for (auto& child : _children) {
|
||||
if (child.getBounds().contains(triangle)) {
|
||||
child.insert(triangleIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if it doesn't exist in an existing child, then check for new possible children
|
||||
// note: this will actually re-check the bounds of all the existing children as well, hmmm
|
||||
for (int child = 0; child < MAX_CHILDREN; child++) {
|
||||
AABox childBounds = getBounds().getOctreeChild((AABox::OctreeChild)child);
|
||||
if (childBounds.contains(triangle)) {
|
||||
|
||||
// create a child node
|
||||
auto child = TriangleOctreeCell(_allTriangles, childBounds, _depth + 1);
|
||||
_children.push_back(child);
|
||||
|
||||
// insert this triangle into it
|
||||
child.insert(triangleIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// either we're at max depth, or the triangle doesn't fit in one of our
|
||||
// children and so we want to just record it here
|
||||
|
@ -206,16 +226,23 @@ bool TriangleOctreeCell::findRayIntersection(const glm::vec3& origin, const glm:
|
|||
return false; // no triangles below here, so we can't intersect
|
||||
}
|
||||
|
||||
float bestLocalDistance = std::numeric_limits<float>::max();
|
||||
float bestLocalDistance = distance; // std::numeric_limits<float>::max();
|
||||
BoxFace bestLocalFace;
|
||||
glm::vec3 bestLocalNormal;
|
||||
bool intersects = false;
|
||||
|
||||
// if the ray intersects our bounding box, then continue
|
||||
if (getBounds().findRayIntersection(origin, direction, bestLocalDistance, bestLocalFace, bestLocalNormal)) {
|
||||
bestLocalDistance = std::numeric_limits<float>::max();
|
||||
|
||||
float childDistance = std::numeric_limits<float>::max();
|
||||
// if the intersection with our bounding box, is greater than the current best distance (the distance passed in)
|
||||
// then we know that none of our triangles can represent a better intersection and we can return
|
||||
if (bestLocalDistance > distance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bestLocalDistance = distance; // std::numeric_limits<float>::max();
|
||||
|
||||
float childDistance = distance; // std::numeric_limits<float>::max();
|
||||
BoxFace childFace;
|
||||
glm::vec3 childNormal;
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
|
||||
const AABox& getBounds() const { return _bounds; }
|
||||
|
||||
size_t size() const { return _triangleIndices.size(); }
|
||||
|
||||
protected:
|
||||
std::vector<Triangle>& _allTriangles;
|
||||
std::vector<int> _triangleIndices;
|
||||
|
@ -52,7 +54,6 @@ public:
|
|||
void insert(int triangleIndex);
|
||||
void reset(const AABox& bounds, int depth = 0);
|
||||
void clear();
|
||||
void prune();
|
||||
|
||||
// Determine if the given ray (origin/direction) in model space intersects with any triangles in the set. If an
|
||||
// intersection occurs, the distance and surface normal will be provided.
|
||||
|
|
Loading…
Reference in a new issue