yael
yael

Reputation: 21

screen to world coordinates in javascript webgl

I'm trying to find a point (screen to world coordinates) in my data by using the following code (based on Click to zoom in WebGL):

    var world1 = [0,0,0,0] ;
    var world2 = [0,0,0,0] ;
    var dir    = [0,0,0] ;
    var w      = event.srcElement.clientWidth ;
    var h      = event.srcElement.clientHeight ;
    // calculate x,y clip space coordinates
    var x      = (event.offsetX-w/2)/(w/2) ;
    var y      = -(event.offsetY-h/2)/(h/2) ;
    mat4.inverse(pvMatrix, pvMatrixInverse) ;
    // convert clip space coordinates into world space
    mat4.multiplyVec4(pvMatrixInverse, [x,y,0,1], world1) ;

for simplicity's sake I have set up a series of vertices where the z coordinate is always 0: coordinates I'm graphing:

0.0 0.0 0.0
1.0 1.0 0.0
1.0 0.0 0.0
0.0 1.0 0.0
0.5 0.5 0.0

Then I compare the values in world1 to my vertices. The values in world1 do not match to where I know I've clicked. Can anyone help with this?

Upvotes: 1

Views: 4385

Answers (2)

sinisterchipmunk
sinisterchipmunk

Reputation: 2023

Please see my similar answer at How to get object in WebGL 3d space from a mouse click coordinate.

TL;DR: I don't think your unproject function is complete. Take a look at the source at jax/camera.js#L568 for another implementation. See also the glhUnProjectf C implementation, which the former is (loosely) based upon.

One last thing. Be careful about the HTML canvas element. Quite often, it's not positioned where you think it is and the only way to make the pixel locations accurate is to traverse upward through the DOM. See jax/events.js#L6 and jax/events.js#L100 for examples of that. Or use the jQuery $('#canvas').offset() function and be done with it. :)

Upvotes: 1

brainjam
brainjam

Reputation: 19005

In general when you "unproject" a clip space point like [x,y,z,1] you will get a point on a ray emanating from the eye point (and in your case going through the vertex you clicked on). The value of z will determine where you are on that ray. You're almost guaranteed to not get back the point you clicked on.

So what you want to do is calculate that ray (say by unprojecting two points like [x,y,0,1] and [x,y,1,1] and calculating the line that the unprojected points are on), and then testing which of your vertices lies on that ray.

Edit: Also, you want to make sure that you've divided the first three coordinates of world1 by the fourth coordinate.

Upvotes: 0

Related Questions