Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
Posted 14 August 2005 - 10:04 AM
Posted 14 August 2005 - 12:54 PM
static bool RaySlabIntersect(float slabmin, float slabmax, float raystart, float rayend, float& tbenter, float& tbexit)
{
float raydir = rayend - raystart;
// ray parallel to the slab
if (fabs(raydir) < 1.0E-9f)
{
// ray parallel to the slab, but ray not inside the slab planes
if(raystart < slabmin || raystart > slabmax)
{
return false;
}
// ray parallel to the slab, but ray inside the slab planes
else
{
return true;
}
}
// slab's enter and exit parameters
float tsenter = (slabmin - raystart) / raydir;
float tsexit = (slabmax - raystart) / raydir;
// order the enter / exit values.
if(tsenter > tsexit)
{
swapf(tsenter, tsexit);
}
// make sure the slab interval and the current box intersection interval overlap
if (tbenter > tsexit || tsenter > tbexit)
{
// nope. Ray missed the box.
return false;
}
// yep, the slab and current intersection interval overlap
else
{
// update the intersection interval
tbenter = max(tbenter, tsenter);
tbexit = min(tbexit, tsexit);
return true;
}
}
static bool SegmentAABBoxIntersect(const CAABBox1& Box, const CSegment1& Seg, float &tinter)
{
// initialise to the segment's boundaries.
float tenter = 0.0f, texit = 1.0f;
// test X slab
if (!RaySlabIntersect(Box.Min.x, Box.Max.x, Seg.Start.x, Seg.End.x, tenter, texit))
{
return false;
}
// test Y slab
if (!RaySlabIntersect(Box.Min.y, Box.Max.y, Seg.Start.y, Seg.End.y, tenter, texit))
{
return false;
}
// test Z slab
if (!RaySlabIntersect(Box.Min.z, Box.Max.z, Seg.Start.z, Seg.End.z, tenter, texit))
{
return false;
}
// all intersections in the green. Return the first time of intersection, tenter.
tinter = tenter;
return true;
}
Posted 14 August 2005 - 01:23 PM
bool Intersection::Intersect(const Vector3& p1, const Vector3& p2, const Vector3& min, const Vector3& max)
{
Vector3 d = (p2 - p1) * 0.5f;
Vector3 e = (max - min) * 0.5f;
Vector3 c = p1 + d - (min + max) * 0.5f;
Vector3 ad = d.Absolute(); // Returns same vector with all components positive
if (fabsf(c[0]) > e[0] + ad[0])
return false;
if (fabsf(c[1]) > e[1] + ad[1])
return false;
if (fabsf(c[2]) > e[2] + ad[2])
return false;
if (fabsf(d[1] * c[2] - d[2] * c[1]) > e[1] * ad[2] + e[2] * ad[1] + EPSILON)
return false;
if (fabsf(d[2] * c[0] - d[0] * c[2]) > e[2] * ad[0] + e[0] * ad[2] + EPSILON)
return false;
if (fabsf(d[0] * c[1] - d[1] * c[0]) > e[0] * ad[1] + e[1] * ad[0] + EPSILON)
return false;
return true;
}
template <class T> bool IntersectLineAABB(
const Vector3<T>& O,
const Vector3<T>& D,
const Vector3<T>& min,
const Vector3<T>& max,
T t[],
T epsilon)
{
Vector3<T> C = (min + max) * (T)0.5;
Vector3<T> e = (max - min) * (T)0.5;
int parallel = 0;
bool found = false;
Vector3<T> d = C - O;
for (int i = 0; i < 3; ++i)
{
if (Math<T>::Fabs(D[i]) < epsilon)
parallel |= 1 << i;
else
{
T es = (D[i] > (T)0.0) ? e[i] : -e[i];
T invDi = (T)1.0 / D[i];
if (!found)
{
t[0] = (d[i] - es) * invDi;
t[1] = (d[i] + es) * invDi;
found = true;
}
else
{
T s = (d[i] - es) * invDi;
if (s > t[0])
t[0] = s;
s = (d[i] + es) * invDi;
if (s < t[1])
t[1] = s;
if (t[0] > t[1])
return false;
}
}
}
if (parallel)
for (int i = 0; i < 3; ++i)
if (parallel & (1 << i))
if (Math<T>::Fabs(d[i] - t[0] * D[i]) > e[i] || Math<T>::Fabs(d[i] - t[1] * D[i]) > e[i])
return false;
return true;
}
Posted 14 August 2005 - 05:58 PM
Quote:Sure.
Thanks. But could you explain what your doing in that Boolean test. I don’t just want a code solution that works; I want to understand the concept as well.
Posted 14 August 2005 - 06:27 PM
Posted 14 August 2005 - 09:54 PM
Posted 15 August 2005 - 01:37 AM
Quote:Yeah. Quoting from my earlier post:
I'm not seeing where you do the cross product? Has that been factored out some how?
Quote:You could write the function using actual cross and dot products. But once you remove all the redundant multiplications by 1 and 0, you end up with the posted code.
Since the box axis components are all 1's and 0's, a lot of the operations drop out and we're left with the code I posted.
Quote:d is half of the segment direction vector, so p1 + d is the segment center. (min + max) * 0.5 is the AABB center. So this expression is basically c = segCenter-boxCenter, which effectively translates the problem so that the box is centered at the origin.
And what is the significance of this point? Vector3 c = p1 + d - (min + max) * 0.5f;
Quote:Yes, you can transform the segment into local OBB space and do an AABB test, or you can just do the SAT test in place using the OBB axes. Either way it comes down to the same thing, but with the former method you can make use of the segment/AABB function you already have.
Also could this be easily adapted to an OBB if you transform the Segment into the OBB's local coordinate space then treat it as an AABB?
Posted 15 July 2011 - 09:55 AM
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
GameDev.net™, the GameDev.net logo, and GDNet™ are trademarks of GameDev.net, LLC.