Hi everyone, I'm hoping for some help. I'm a total beginner and struggling even to phrase this question, so apologies if this doesn't make much sense!
Ultimately I would like to select objects in a 3D space with the mouse, using what I believe is called 'ray picking' - I want to push a line directly into the screen from the mouse position and see what it intersects. My problem is that I can't work out how to find that vector - the line that pushes straight back into the screen from the pointer.
In the following code, I am using peasyCam to look around a box which is simply there as a visual reference in the space. The camera is looking at the origin (0,0,0) in model space. I can find the looked-at-point, camera and mouse position in the model space, and so define the vectors between them. That means I can do something like push the camera-to-looked-at-point vector back twice from the mouse position, to find a kind of 'mirrored' mouse position, the position on an equivalent screen on the other side of the space. I've drawn a line from the origin to this point, just to illustrate it. This moves with the mouse, as you'd expect, but because of the perspective doesn't have the same screenX/Y values. I need to find the point on this 'back screen' which has the same screenX/Y values as the mouse pointer.
Basically I'm looking for a way to find a distant point with the same screenX/Y values as the mouse, which I can use to create my needed vector. Any ideas?
Thank you for your help :-)
import peasy.*; //peasyCam
PeasyCam cam; //peasyCam
//set-up
void setup() {
size(800, 600, P3D); //screen size and 3D renderer
cam = new PeasyCam(this, 0, 0, 0, 500); //peasyCam inital lookAt(x,y,x,distance)
cam.setMinimumDistance(200); //minimum camera distance from subject, constrains zoom
cam.setMaximumDistance(500); //maximum camera distance from subject, constrains zoom
} //end setup()
//begin draw loop
void draw() {
background(0); //clears screen
//draw box just for a visual reference in the 3D space
noFill(); //box fill colour
stroke(150, 150, 150, 255); //box line colour
strokeWeight(2); //box line thickness
box(300, 300, 300); //box size (x,y,z)
float[] rotations = cam.getRotations(); //camera rotations in model space (x,y,z)
float lookedAt[]=cam.getLookAt(); //lookedAt coordinates in model space (x,y,z)
float camPos[]=cam.getPosition(); //camera coordinates in model space (x,y,z)
float distance=dist(lookedAt[0], lookedAt[1], lookedAt[2], camPos[0], camPos[1], camPos[2]); //distance from camera to looked at point
//this finds the position of the mouse in model space
float[] mousePos=new float[3]; //mouse coordinates in model space (x,y,z)
pushMatrix();
rotateX(rotations[0]);
rotateY(rotations[1]);
rotateZ(rotations[2]);
mousePos[0]=modelX(mouseX-width/2, mouseY-height/2, distance);
mousePos[1]=modelY(mouseX-width/2, mouseY-height/2, distance);
mousePos[2]=modelZ(mouseX-width/2, mouseY-height/2, distance);
popMatrix();
//vector from camera position to mouse position in model space
PVector camToMouse;
camToMouse=new PVector(mousePos[0]-camPos[0], mousePos[1]-camPos[1], mousePos[2]-camPos[2]);
//vector from camera position to looked at position in model space
PVector camToLookedAt;
camToLookedAt=new PVector(lookedAt[0]-camPos[0], lookedAt[1]-camPos[1], lookedAt[2]-camPos[2]);
//line from origin to 'mirrored' mouse position
line(0,0,0,mousePos[0]+2*camToLookedAt.x,mousePos[1]+2*camToLookedAt.y,mousePos[2]+2*camToLookedAt.z);
//prints distance from mouse position to mirrored mouse position (just to check!)
println(dist(mousePos[0],mousePos[1],mousePos[2],mousePos[0]+2*camToLookedAt.x,mousePos[1]+2*camToLookedAt.y,mousePos[2]+2*camToLookedAt.z));
} //end draw()