Object picking with Ray casting in elm-webgl -


demo (?) working example: https://ellie-app.com/4h9f8fncrpya1/1
demo: click draw ray, , rotate camera left , right see ray. (as origin camera, can't see position created)

context
working on elm & elm-webgl project know if mouse on object when clicked. tried implement simple ray cast. need 2 things:
1) coordinate of camera (this 1 easy)
2) coordinate/direction in 3d space of clicked

problem
steps 2d view space 3d world space understand are:
a) make coordinates in range of -1 1 relative view port
b) invert projection matrix , perspective matrix
c) multiply projection , perspective matrix
d) create vector4 normalised mouse coordinates
e) multiply combined matrices vector4
f) normalise result

try far
have made function transform mouse.position coordinate draw line to:

getclickposition : model -> mouse.position -> vec3 getclickposition model pos =     let         x =             tofloat pos.x          y =             tofloat pos.y          normalizedposition =             ( (x * 2) / 1000 - 1, (1 - y / 1000 * 2) )          homogeneousclipcoordinates =             vec4.vec4                 (tuple.first normalizedposition)                 (tuple.second normalizedposition)                 -1                 1          inversedprojectionmatrix =             maybe.withdefault mat4.identity (mat4.inverse (camera model))          inversedperspectivematrix =             maybe.withdefault mat4.identity (mat4.inverse perspective)          inversedmatrix2 =             mat4.mul inversedprojectionmatrix inversedperspectivematrix          =             vec4.vec4                 (tuple.first normalizedposition)                 (tuple.second normalizedposition)                 1                 1          toinversed =             mulvector inversedmatrix2          tonorm =             vec4.normalize toinversed          tovec3 =             vec3 (vec4.getx tonorm) (vec4.gety tonorm) (vec4.getz tonorm)     in         tovec3 

result
result of function rays center click. added screenshot clicked in 4 of top face of cube. if click on center of viewport ray correctly positioned.

it feels close, not quite there yet , can't figure out doing wrong!

example image of current situation

after trying other approaches found solution:

getclickposition : model -> mouse.position -> vec3 getclickposition model pos =     let         x =             tofloat pos.x          y =             tofloat pos.y          normalizedposition =             ( (x * 2) / 1000 - 1, (1 - y / 1000 * 2) )          homogeneousclipcoordinates =             vec4.vec4                 (tuple.first normalizedposition)                 (tuple.second normalizedposition)                 -1                 1          inversedviewmatrix =             maybe.withdefault mat4.identity (mat4.inverse (camera model))          inversedprojectionmatrix =             maybe.withdefault mat4.identity (mat4.inverse perspective)          vec4cameracoordinates = mulvector inversedprojectionmatrix homogeneousclipcoordinates          direction = vec4.vec4 (vec4.getx vec4cameracoordinates) (vec4.gety vec4cameracoordinates) -1 0          vec4worldcoordinates = mulvector inversedviewmatrix direction          vec3worldcoordinates = vec3 (vec4.getx vec4worldcoordinates) (vec4.gety vec4worldcoordinates) (vec4.getz vec4worldcoordinates)          normalizedvec3worldcoordinates = vec3.normalize vec3worldcoordinates          origin = model.camerapos          scaleddirection = vec3.scale  20 normalizedvec3worldcoordinates          destination = vec3.add origin scaleddirection      in         destination 

i left verbose possible, if finds use incorrect terminology please make comment , update answer.

i sure there lots of optimisations possible (multiplying matrices before inverting or combining of steps.)

updated ellie app here: https://ellie-app.com/4hz9s8s92psa1/0


Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -