3d Projection by hand

I am working on a new idea, for graphics I’m using the cool 3d stuff, namely:

camera(eyeposition, eyedirection)
perspective()

then for drawing each object

pushMatrix()
translate(object.position)
rotate(object.anglevector)
drawstuff
popMatrix()

This all works lovely. However I want to do like a HUD thing tagging the items in the “foreground” so while all the mojo draws it right, I need to be able to calculate from the info: eyeposition, eyedirection, object.position what the x,y screen pixel location that ends up as.

I was guessing some combination of viewMatrix() perspectiveMatrix() multiplied by object.position or something would do it, but I honestly am stuck.

Any suggestions of how to do this?

SM

I think the answer could be
modelViewProjection = modelMatrix() * viewMatrix() * projectionMatrix().
Apply this matrix to you point coodinate vec4(x,y,z,0) to get the screen position. Hem. Wait… The mat x vec operation does not work, so you have to put the point coordinates in the 1rst row or 1rst column of a 4x4 matrix, don’t remember which one., and read the result out of first row or column.
(copy/paste from a hidden beta 1.5 thread.) Simeon, Mpilgrem or Andreaw_Stacey will correct me if i am wrong.

Ah yes, I think I almost had it, but you backed up my thinking. I was being thrown off by 2 things… the 3rd and 4th numbers in the resulting matrix contain rubbish, and the resulting x & y are based on the centre of the screen being the origin (0,0).

I think it’s working and will play with my code tomorrow to confirm.

Thanks

Here’s my tutorial on these things: http://loopspace.mathforge.org/discussion/13/matrices-in-codea. Hope it helps, feel free to ask here about it.

Your tutorial got me there eventually…

Basically before the below snippet I have done a camera(eye,direction) and perspective() call.

The key thing was that from the reverse projection it projects to the centre of the screen being (0,0) and the width and height being (-1 <-> 1)… once you convert the result for those it’s easy :wink:

Then I just had to check z position otherwise it was redrawing once they were behind me…

resetMatrix()
    translate(self.position.x, self.position.y, self.position.z)
    rotate(self.direction.x, self.direction.y, self.direction.z)
    ellipse(0,0,50)
    
    local l = modelMatrix()*viewMatrix()*projectionMatrix()
    if l[15] > 0 then
        self.screenPosition = vec2((l[13]/l[16]+1)*WIDTH/2,(l[14]/l[16]+1)*HEIGHT/2)
    else
        self.screenPosition = nil
    end

So, my next task is rotating the camera based on touch… since this is a space esque concept, I’m thinking free rotation rather than tieing the user to some artificial horizon…

I am struggling to grok some of the maths I need, math class was too many years ago, but I think quaternions probly using @Andrew_Stacey’s library. Is that a sensible way to go?

Of course this is just the start of the maths, I’ll be calculating orbital mechanics soon :wink:

.@spacemonkey I don’t know how easy it would be to use my code (since all my separate libraries tend to be linked together), but at least for the ideas then you could look at my View library. This does what you want, I think. You can get the code (and all dependent code) at http://www.math.ntnu.no/~stacey/code/CodeaLibrary.

And, yes, it does use quaternions!