(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.

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 on other sites
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 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 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.

1. 1
Rutin
34
2. 2
3. 3
4. 4
5. 5

• 12
• 14
• 9
• 9
• 9
• Forum Statistics

• Total Topics
633337
• Total Posts
3011415
• Who's Online (See full list)

There are no registered users currently online

×