Jump to content


line intersecting plane in isometric


7 replies to this topic

#1 greenbean

    New Member

  • Members
  • Pip
  • 1 posts

Posted 24 December 2006 - 06:13 PM

I have my camera set to an orthographic/isometric style projection and I am trying to see where the mouse position intersects the floor plane. What I'm using works fine in a regular perspective but it is not right for ortho. I'm new to 3d and not really a math genius so if anyone can help me to make this work I would really appreciate it.

This is for the source engine so I dunno if that matters but I assume the concepts should be the same no matter what I'm using. I can post code I am using if required.

#2 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 309 posts

Posted 30 December 2006 - 06:31 PM

I'll add to the line on this one.
I too can't cast rays into Orthogonal view to pick objects with the mouse.

Help, please.
Thanks In Advance (and Happy New Year).

Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#3 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 30 December 2006 - 07:21 PM

In a regular perspective view, you let the ray start at the camera location and choose the direction so that it pierces the appropriate screen pixel. However, in an orthogonal view all the rays will be travelling the same direction. You have to offset the ray origin from the camera based on the pixel that was clicked.
reedbeta.com - developer blog, OpenGL demos, and other projects

#4 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 309 posts

Posted 30 December 2006 - 10:13 PM

The moment you mentioned the word offset,
I realized what you were getting at and why it was needed.

Heh. I kept repeating to myself: "rays are parallel now",
and yet I wouldn't notice the solution at hand!

Thank you so much, Reed :yes:
Best Regards.

Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#5 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 309 posts

Posted 31 December 2006 - 04:12 PM

Update:
I still can't get it to work :angry:
Wasted the whole night yesterday on this ridicolous problem.
Here is a simplified version of the code I use to setup the ray:


//

    // NOTES:

    //

    //     MouseX, MouseY, ScreenW and ScreenH are in Pixels.

    //     Proj.m11 = 2 / ViewportW    (in Units).

    //     Proj.m22 = 2 / ViewportH    (in Units).

    //     iView is the Inverse of the View[4,4] matrix.

    //

    //     (Direct3D matrix convention is used)


    float RayEndX = (2.0f * MouseX / ScreenW - 1.0f) / Proj.m11;

    float RayEndY = (1.0f - 2.0f * MouseY / ScreenH) / Proj.m22;


    Vec3 RayStart;

    Vec3 RayDir;


    // Problem is here, no?

    RayStart.x = iView.m41;

    RayStart.y = iView.m42;

    RayStart.z = iView.m43;


    RayDir.x   = RayEndX * iView.m11 + RayEndY * iView.m21 + iView.m31;

    RayDir.y   = RayEndX * iView.m12 + RayEndY * iView.m22 + iView.m32;

    RayDir.z   = RayEndX * iView.m13 + RayEndY * iView.m23 + iView.m33;

I am begging for help.
Please tell me what needs to be changed and how.
I'm totally out of ideas.



Side note:
Since all rays are parallel, I can copy the Normal Vector of
the Near Clipping Plane (which faces the inside of the Frustum)
and assume it to be the Ray direction. Right?



Regards,
Ciao ciao : (
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#6 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 31 December 2006 - 06:36 PM

Look at what you're doing. You're setting the ray origin to the camera location, and you're calculating the ray direction based on the mouse click. That's backward. The ray direction is constant; you need to offset the ray origin by the mouse click! You can do this by using your RayEnd vector as the ray origin in eye space, and (0, 0, 1) as the ray direction (assuming D3D's left-handed coordinate system), and transforming both by the inverse view matrix.
reedbeta.com - developer blog, OpenGL demos, and other projects

#7 Nautilus

    Senior Member

  • Members
  • PipPipPipPip
  • 309 posts

Posted 01 January 2007 - 04:58 PM

It works just fine now.
Thank you once more, for your patience and input :happy:

Searching for a solution to this problem, I've found plenty of posts on other forums.
None of them featured the right answer (can you believe that?)

Sooner or later someone else will face this same problem and he'll land on DevMaster,
looking for answers.

Thus I leave a working code snippet here:

//

    // NOTES:

    //     iView is the Inverse of the View Matrix.

    //     Proj is the Projection Matrix.

    //     MouseX, MouseY, ScreenW and ScreenH are in Pixels.

    //

    //     The Ray built here is in World space: NOT suitable to test

    //     objects for intersection, unless they use an Identity World

    //     Matrix.

    //

    //     For faster Ray intersection tests with objects not in World

    //     space, do not transform the Object into World space, but

    //     rather transform the Ray into Object space.




    // Converts coords from Pixels to Units

    float CoordX = (2.0f * MouseX / ScreenW - 1.0f) / Proj.m11;

    float CoordY = (1.0f - 2.0f * MouseY / ScreenH) / Proj.m22;


    Vec3 RayStart, RayDir;


    // What Projection Matrix were we given?

    if (!Proj.m44) // Proj.m44 == 0.0f

    {

        // Projection Matrix : Perspective

        // -------------------------------


        // Same as using D3DXVec3TransformCoord(), just faster.

        // RayStart untransformed Coordinates Vector is (x0,y0,z0) in

        // Camera space, hence the optimization.

        RayStart.x = iView.m41;

        RayStart.y = iView.m42;

        RayStart.z = iView.m43;


        // Same as using D3DXVec3TransformNormal()

        RayDir.x = CoordX * iView.m11 + CoordY * iView.m21 + iView.m31;

        RayDir.y = CoordX * iView.m12 + CoordY * iView.m22 + iView.m32;

        RayDir.z = CoordX * iView.m13 + CoordY * iView.m23 + iView.m33;

    }

    else // Proj.m44 == 1.0f

    {

        // Projection Matrix : Orthogonal

        // ------------------------------

        // Credits here go to "Reedbeta" of www.DevMaster.net

        // Practically HE wrote this, not me =P


        // Same as using D3DXVec3TransformCoord()

        // Transforms a 3D Vector by the given Matrix, and projects result

        // back into w=1

        // Then discard w (we never liked it anyway)

        float    w = 1.0f / (CoordX * iView.m14 + CoordY * iView.m24 + iView.m44);

        RayStart.x = w * (CoordX * iView.m11 + CoordY * iView.m21 + iView.m41);

        RayStart.y = w * (CoordX * iView.m12 + CoordY * iView.m22 + iView.m42);

        RayStart.z = w * (CoordX * iView.m13 + CoordY * iView.m23 + iView.m43);


        // Same as using D3DXVec3TransformNormal(), just faster.

        // RayDir untransformed Normal Vector is (x0,y0,z1) in Camera space,

        // hence the optimization

        RayDir.x = iView.m31;

        RayDir.y = iView.m32;

        RayDir.z = iView.m33;

    }


Kind regards,
Ciao ciao : )
-Nautilus

(readin' this? perhaps you should get out more -- give it a thought)


#8 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 01 January 2007 - 07:48 PM

Cool, glad to see you got it figured out. :yes:
One minor detail: it's devmaster.net, not .com ;)
reedbeta.com - developer blog, OpenGL demos, and other projects





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users