aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorclick <none@none>2010-07-15 19:43:47 +0200
committerclick <none@none>2010-07-15 19:43:47 +0200
commitd2b4ffbec37499259f1c26cf8e2142b012f9f6bd (patch)
tree9015e9aeb4298ab352cc63626f72f554a59f8c8b /src
parenta214443409068257f19c00f5855f3352c550bffc (diff)
Use a slightly different approach to tree bound intersection (by Lynx3d)
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.h34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
index d4d41a66d30..1e1955641cf 100644
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ b/src/server/collision/BoundingIntervalHierarchy.h
@@ -116,32 +116,36 @@ class BIH
template<typename RayCallback>
void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
{
- float intervalMin = 0.f;
- float intervalMax = maxDist;
+ float intervalMin = -1.f;
+ float intervalMax = -1.f;
Vector3 org = r.origin();
Vector3 dir = r.direction();
Vector3 invDir;
- float t1, t2;
- for(int i=0; i<3; ++i)
+ for (int i=0; i<3; ++i)
{
invDir[i] = 1.f / dir[i];
- t1 = (bounds.low()[i] - org[i]) * invDir[i];
- t2 = (bounds.high()[i] - org[i]) * invDir[i];
- if (invDir[i] > 0) {
+ if (dir[i] != 0.f)
+ {
+ float t1 = (bounds.low()[i] - org[i]) * invDir[i];
+ float t2 = (bounds.high()[i] - org[i]) * invDir[i];
+ if (t1 > t2)
+ std::swap(t1, t2);
if (t1 > intervalMin)
intervalMin = t1;
- if (t2 < intervalMax)
+ if (t2 < intervalMax || intervalMax < 0.f)
intervalMax = t2;
- } else {
- if (t2 > intervalMin)
- intervalMin = t2;
- if (t1 < intervalMax)
- intervalMax = t1;
+ // intervalMax can only become smaller for other axis,
+ // and intervalMin only larger respectively, so stop early
+ if (intervalMax <= 0 || intervalMin >= maxDist)
+ return;
}
- if (intervalMin > intervalMax)
- return;
}
+ if (intervalMin > intervalMax)
+ return;
+ intervalMin = std::max(intervalMin, 0.f);
+ intervalMax = std::min(intervalMax, maxDist);
+
uint32 offsetFront[3];
uint32 offsetBack[3];
uint32 offsetFront3[3];