Jump to content
  • Advertisement
Sign in to follow this  
ktuluorion

(ray) Intersection with a cube

This topic is 4816 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I finally managed to get my picking working (kinda). Can anybody point me to a function (or the best way) to check for an intersection with a cube once I have my ray?

Share this post


Link to post
Share on other sites
Advertisement
I see d3dxboxboundprobe, but unfortunately that does not have a distance variable so you know how close objects are. Is there anything similar that gives you a distance?

Share this post


Link to post
Share on other sites
Hi there ktuluorion,
How are you doing?

The Problem
Intersection with a mesh using a ray.

The Solution
Mesh intersection
You could use the D3DXIntersect Function.

Other intersection
If your cube is not a mesh you could use other ways of checking if your ray is intersecting with it like creating a new ID3DXMesh and inserting your values into it's vertex buffer and doing a D3DXIntersect to check if the ray intersects

For picking I normally use the following methods
1) Get the mouse coordinates in screen space
2) Calculate a near and far vector for the mouse coordinates.
example:
D3DXVECTOR3 near;
near.x = Cursor.x;
near.y = Cursor.y;
near.z = 0.0f;
D3DXVECTOR3 far;
near.x = Cursor.x;
near.y = Cursor.y;
near.z = 1.0f;
3) I then use the D3DXVec3Unproject function to unproject both vectors
4) If you subtract the 2 vectors from each other you get a resulting directional ray.
5) Use the D3DXIntersect method and give it your vectors
near being your ray position
far - near being your directional ray.
I hope this helps. Take care buddy

Share this post


Link to post
Share on other sites
Here's some code that returns the parametric values for the intersection of a line and an axis-aligned box:

template <class T> bool Math3D<T>::IntersectLineAABB(
const Vector3<T>& O, // Line origin
const Vector3<T>& D, // Line direction
const Vector3<T>& C, // AABB center
const Vector3<T>& e, // AABB extents
T t[2], // Parametric intersection values
T epsilon) // Epsilon for parallel test (set to some suitably small value)
{
int parallel = 0;
bool found = false;
Vector3<T> d = C - O;
for (int i = 0; i < 3; ++i)
{
if (Math<T>::Fabs(D) < epsilon)
parallel |= 1 << i;
else
{
T es = (D > (T)0.0) ? e : -e;
T invDi = (T)1.0 / D; // It is possible to defer the division, but I don't think it's worth the effort here

if (!found)
{
t[0] = (d - es) * invDi;
t[1] = (d + es) * invDi;
found = true;
}
else
{
T s = (d - es) * invDi;
if (s > t[0])
t[0] = s;
s = (d + 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 - t[0] * D) > e || Math<T>::Fabs(d - t[1] * D) > e)
return false;

return true;
}

For rays and segments, simply reject values of t outside the appropriate range. Here's the OBB version:

template <class T> bool Math3D<T>::IntersectLineOBB(
const Vector3<T>& O, // Line origin
const Vector3<T>& D, // Line direction
const Vector3<T>& C, // OBB center
const Vector3<T> A[], // OBB axes (unit length)
const Vector3<T>& e, // OBB extents
T t[], // Parametric intersection values
T epsilon) // Epsilon for parallel test (set to some suitably small value)
{
int parallel = 0;
bool found = false;
T DA[3];
T dA[3];
Vector3<T> d = C - O;
for (int i = 0; i < 3; ++i)
{
DA = D.Dot(A);
dA = d.Dot(A);
if (Math<T>::Fabs(DA) < epsilon)
parallel |= 1 << i;
else
{
T es = (DA > (T)0.0) ? e : -e;
T invDA = (T)1.0 / DA;

if (!found)
{
t[0] = (dA - es) * invDA;
t[1] = (dA + es) * invDA;
found = true;
}
else
{
T s = (dA - es) * invDA;
if (s > t[0])
t[0] = s;
s = (dA + es) * invDA;
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(dA - t[0] * DA) > e || Math<T>::Fabs(dA - t[1] * DA) > e)
return false;

return true;
}

I'll be happy to explain what the code does if you're interested.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!