aboutsummaryrefslogtreecommitdiff
path: root/src/server/collision/BoundingIntervalHierarchy.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/collision/BoundingIntervalHierarchy.h')
-rw-r--r--src/server/collision/BoundingIntervalHierarchy.h42
1 files changed, 23 insertions, 19 deletions
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
index 15ae90c23eb..1e1955641cf 100644
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ b/src/server/collision/BoundingIntervalHierarchy.h
@@ -19,11 +19,11 @@
#ifndef _BIH_H
#define _BIH_H
-#include <G3D/Vector3.h>
-#include <G3D/Ray.h>
-#include <G3D/AABox.h>
+#include "G3D/Vector3.h"
+#include "G3D/Ray.h"
+#include "G3D/AABox.h"
-#include <Platform/Define.h>
+#include "Define.h"
#include <stdexcept>
#include <vector>
@@ -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];