Couldn't think of a snappier title unfortunately...
Right, I had a problem. Given a known camara position/direction, and the on screen x/y co-ordinates fo the mouse, find that 3d-world-coordinates tha the mouse is covering.
This turne dout to be significantly more complex than I had imagined, and unfortunately does require intersect testing world-polygons, as well as significant ammounts of vector calculations, and I'm sure there must be a better way to do it.
For reference, here is the current code I need to run to find out where abouts on the x/y (z=0) plane the mouse cursor is, from a given camera position:
Code:
camera(0,-50,50,0,0,0,0,0,-1); //setup camera
fill(128,200,128); // a small chunk of th eplane, so we can see object is "on" it.
beginShape(QUADS);
{
vertex(-50,-50,0);
vertex(50,-50,0);
vertex(50,50,0);
vertex(-50,50,0);
}
endShape();
Vector camPos=new Vector(0,-50,50);
Vector camDir=new Vector(0,1,-1);
Vector left=cross(new Vector(0,0,1),camDir); // use temporary "up" until we can calculate the actual version
Vector up=cross(camDir,left);
Vector tmp=rotate(camDir,up,-PI/6.0); // vector along the left side of the view frustrum
Vector tmp2=rotate(camDir,left,-PI/6.0); // vector along the top of the view frustrum
Vector[] camPlane=new Vector[3]; // a plane for us to map on-screen values to.
camPlane[0]=add(new Vector(0,0,0),add(mul(left,1000),mul(up,1000)));
camPlane[1]=add(new Vector(0,0,0),add(mul(left,1000),mul(up,-1000)));
camPlane[2]=add(new Vector(0,0,0),mul(left,-1000));
// find the co-ordinates where the middle/left/top vectors intersect this plane.
Vector mid=intersectPoint(camPlane[0],camPlane[1],camPlane[2],camPos,add(camPos,mul(camDir,300)));
Vector leftEdge=intersectPoint(camPlane[0],camPlane[1],camPlane[2],camPos,add(camPos,mul(tmp,300)));
Vector topEdge=intersectPoint(camPlane[0],camPlane[1],camPlane[2],camPos,add(camPos,mul(tmp2,300)));
//what change does one pixel make
Vector deltaX=div(dir(mid,leftEdge),(float)width/2.0);
Vector deltaY=div(dir(mid,topEdge),(float)height/2.0);
// convert mouse X and Y co-ordinates into vectors in the camPlane
Vector mouseVectorX=add(leftEdge,mul(deltaX,constrain(mouseX,0,width-1)));
Vector mouseVectorY=add(topEdge,mul(deltaY,constrain(mouseY,0,height-1)));
// the Vector in the camera plane of the mouse, from the top left corner
Vector mousePlaneVector=add(mouseVectorX,mouseVectorY);
// the vector from the camera to this point in the camPlane
Vector mouseCameraVector=mul(dir(camPos,mousePlaneVector),100);
// finally! the intersection of the mouse pointer with the "ground" plane.
Vector ip=intersectPoint(new Vector(-1000,-1000,0),new Vector(0,1000,0),new Vector(1000,-1000,0),camPos,add(camPos,mouseCameraVector));
As you can see this is huge, and doesn't even include the 40-odd lines of my VectorMaths library that does the intersect/rotation etc.
So.. is there a better way? There's got to be one, that cannot be the best way to get the correct answer.
It *is* possible to simplify it, but it will give a variably wrong answer, especially if I use larger FOV settings, since the screen is mapped to a flat plane, not a curved surface equidistant from the camera.