0

BACKGROUND

Using kivy with openGL and GLU style functions, I have gotten modelview and projection matrices working. The model matrix is not used, so the modelview matrix is just really a transform based upon the location of the camera.

# cx,cy,cz are the location of the camera. cz is always positive
modelview = Matrix().look_at(cx,cy,cz,     # eye position coords
                             cx,cy,0.0,    # looking at this pt.
                             0.0,1.0,0.0)  # a vector pointing up

The projection matrix is also straightforward and working as desired.

aspect_ratio = float(Window.width)/Window.height
projection.perspective(90.0, aspect_ratio, 1.0, 400.0)

The look_at and perspective functions come from kivy's Matrix class which is emulating/encapsulating some GLU functions of the same (or similar) name.

Projection seems to be working just right, but...

PROBLEM

A point on the screen can be thought of as defining a ray from the eye of the camera off to infinity. I'd like to know the world x,y coordinates of where that ray intersects the plane defined by z=0.

Here is (one of) my (many) attempt(s) to get this to work.

x,y  # <--- mouse coords (I've tried range of [0..1], or [0..screenwidth]) 
z=0  # I have also tried z=cz

# create inverse proj. matrix with near set to the distance
# the camera is from z=0
proj = Matrix().identity()
proj.perspective(90.0, aspect_ratio, cz, cz+1.0)
proj_i = proj.inverse()

# create inverse modelview matrix
modelview_i = modelview_mat.inverse()

x,y,z = proj_i.transform_point(x,y,z)
x,y,z = modelview_i.transform_point(x,y,z)

This doesn't work. Specifically, when I have the camera steadily moving away (cz is increasing slowly). The x,y of mouse clicks do not change as the camera moves.

What am I doing wrong?

I know there are many similar questions floating about, but I haven't been able to find the information I am looking for.

weemattisnot
  • 889
  • 5
  • 16
  • 1
    You must include the `w` component when you're dealing with perspective transforms. Set it to `1` before the transformation and divide `x, y, z` by `w` after the transformation. – Nico Schertler Apr 28 '15 at 15:05
  • While I couldn't get this to work, I switched tactics to a geometrical approach to "ray-picking." Following the [pseudocode on Schabby's blog](http://schabby.de/picking-opengl-ray-tracing/), I was able to achieve the desired functionality. – weemattisnot Apr 28 '15 at 19:06

0 Answers0