Search code examples
javascriptcollision-detectionwebgl

Mouse Coords to Game Coords WebGL


I'm trying to translate the mouse x, y coordinates into 3d world coordinates of webgl canvas. I've gotten it working partially, but am having some trouble when the world gets rotated on any axis.

I'm using the unproject method that gets the starting/ending points of the ray and then doing a line to plane collision test for a flat plane with the normal 0, 1, 0 and the point being used is 0, 0, 0.

You can find the code at wingsofexodus.com by doing a view source. The functions being used are RtoW (real to world, for mouse to world conversion), lpi (line plane intersection testing), and unproject.

It's been ages since I had to do any matrix/vector math and dusting off the books after so long is proving difficult.

The site may come up slow, my internet connection for it isn't all that great. If it proves to be to trouble some I'll copy the code to here.

Any help or links that might help is appreciated.


Solution

  • You've got the right idea, but I see two mistakes and one needless complication:

    • Complication: Instead of duplicating the code to compute the view matrix from rotation angles etc, save a copy of it when you compute it (at the beginning of drawScene) and use that instead of mm. Or, make sure the matrix stack is in the right place and have unproject just use mvMatrix. This will avoid errors from that.
    • You refer to the translation in what you do with the unprojection result (in RtoW). This is a mistake, because the translation is already included in mm; you're either doubling or cancelling it. After you have unprojected the mouse coordinates, you have world coordinates which do not need to be further modified before doing your ray collision test.
    • In unproject, you are inverting the view matrix before multiplying it with the projection matrix. You can either do (pseudocode) invert(view)*invert(projection), or (cheaper) invert(projection*view), but you're currently doing invert(projection*invert(view)), which is wrong.

    These are what jumped out at me, but I haven't reviewed all of your code. The unprojection looks OK when I compare it to my own version of the same.