We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello,
I have been trying to write a code for being able to pick objects or select points in 3D by using a ray tracing method, based on the guidelines I read from this source: http://schabby.de/picking-opengl-ray-tracing/
However, I have no idea how to check intersection between the ray and the object in the scene, and also I am not sure that the code is 100% correct. I am posting the code below. If anyone could help it would be great!
import peasy.*;
import toxi.geom.*;
float x;
float y;
// -- camera parameters ---------
PeasyCam cam;
Vec3D camTarget;
Vec3D camPosition;
Vec3D view = new Vec3D();
Vec3D camHorizontal = new Vec3D();
Vec3D camVertical = new Vec3D();
Vec3D pos;
Vec3D dir;
float fov = 1; //PI/5
float aspect = float(width)/float(height);
float nearClip = 1;
float farClip = 100000;
Cube cube0;
// ------------------------------
void setup() {
size(800, 800, OPENGL);
createCamera();
Vec3D start = new Vec3D(0, 0, 0);
cube0 = new Cube(start, 30);
}
// ------------------------------
void draw() {
smooth();
background(255);
cube0.run();
raytracing();
testIntersection();
}
// ------------------------------
void createCamera() {
cam = new PeasyCam(this, 300);
perspective(fov, aspect, nearClip, farClip);
}
// ------------------------------
void raytracing() {
x = mouseX;
y = mouseY;
// --- get camera target position
float a[] = cam.getLookAt();
float a1 = a[0];
float a2 = a[1];
float a3 = a[2];
camTarget = new Vec3D(a1, a2, a3);
// --- get camera position
float b[] = cam.getPosition();
float b1 = b[0];
float b2 = b[1];
float b3 = b[2];
camPosition = new Vec3D(b1, b2, b3);
// --- get view
view = camTarget.sub(camPosition);
view.normalize();
// -- get cameraUp vector
Vec3D Zaxis = new Vec3D(0, 0, 1);
Vec3D rotAxis = view.cross(Zaxis);
float theta = -PI/2;
Vec3D camUp = view.getRotatedAroundAxis(rotAxis, theta);
// -- calculate screenHorizontally and screenVertically
camHorizontal = view.cross(camUp);
camHorizontal.normalize();
camVertical = camHorizontal.cross(view);
camVertical.normalize();
float vLength = tan(fov/2)*nearClip;
float hLength = vLength*aspect;
camVertical.scaleSelf(vLength);
camHorizontal.scaleSelf(hLength);
// translate mouse coordinates so that the origin lies in the center
x -= width/2;
y -= height/2;
x /= (width/2);
y /= (height/2);
// compute intersection of picking ray with viewport plane
float posX = camPosition.x + view.x*nearClip + camHorizontal.x*x + camVertical.x*y;
float posY = camPosition.y + view.y*nearClip + camHorizontal.y*x + camVertical.y*y;
float posZ = camPosition.z + view.x*nearClip + camHorizontal.z*x + camVertical.z*y;
pos = new Vec3D(posX, posY, posZ);
dir = pos.sub(camPosition);
}
// ------------------------------
void testIntersection() {
}
There is also a simple cube class just for displaying and getting the location vector of the cube. Thank you very much for your help! :)
Answers
Is this old thread that discusses the same resource relevant?
yes it's the same question but the source that he is using as his solution is the one that I cannot fully understand, so it doesn't help me in any way
would you like to try exploring this example?
Probably you can implement Peasy Cam. By the way, peasy cam doesn't have an example to use 3D picking?
I think the solution mostly used is to check the position within a plane parallel to the camera plane (in the example the plane is not parallel, but fixed at ground)
I have implemented a method on this code to detect mouseOver function over 3D vertices. But that means looping through a model vertices and check if the 3d position of that vertex in window coordinates matches.
mouseOver check: