I tried following the Nehe tutorial on picking, but aparantly I haven’t understood everything Think you guys could take a look at my method to check for hits? When I change perspectives or change the screen size I make a glFrustum call, but it isn’t called in this method. Does it need to be?
Here’s the method. I hope you guys can help me figure out the problem!
public InteractionTarget getTargetHit(GLDrawable drawable, int mouseX, int mouseY) {
GL gl = drawable.getGL();
int[] viewport = new int[4];
// This Sets The Array <viewport> To The Size And Location Of The Screen Relative To The Window
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport);
//where our hits will be stored
IntBuffer buffer = BufferUtils.newIntBuffer(elements.size());
gl.glSelectBuffer(elements.size(), buffer);
gl.glRenderMode(GL.GL_SELECT);
gl.glInitNames(); // Initializes The Name Stack
gl.glPushName(0);
gl.glMatrixMode(GL.GL_PROJECTION); // Selects The Projection Matrix
gl.glPushMatrix(); // Push The Projection Matrix
gl.glLoadIdentity();
drawable.getGLU().gluPickMatrix(mouseX, viewport[3] - mouseY, 1.0f, 1.0f, viewport);
gl.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
gl.glLoadIdentity();
camera.look(drawable);
//Render all the objects in a Thread safe way
ArrayList elements = getElements();
synchronized (elements) {
//Draw all of the Elements in the scene that have InteractionTargets
for (int i = 0; i < elements.size(); i++) {
Element e = (Element)elements.get(i);
if ((e.getInteractionTarget(Element.TARGET_POSITION) != null
&& e.getInteractionTarget(Element.TARGET_POSITION).isEnabled()) ||
(e.getInteractionTarget(Element.TARGET_SIZE) != null
&& e.getInteractionTarget(Element.TARGET_SIZE).isEnabled()) ) {
System.out.println("checking " + i + " " + e.getClass());
gl.glLoadName(i);
e.draw(drawable);
}
}
}
gl.glMatrixMode(GL.GL_PROJECTION); // Select The Projection Matrix
gl.glPopMatrix(); // Pop The Projection Matrix
gl.glMatrixMode(GL.GL_MODELVIEW); // Select The Modelview Matrix
int hits = gl.glRenderMode(GL.GL_RENDER);
System.out.println("hits: " + hits);
if (hits > 0) {
int choose = buffer.get(3); // Make Our Selection The First Object
long depth = ((long)buffer.get(1)) & 0xFFFFFFFFL;
for (int loop = 1; loop < hits; loop++) {
// If This Object Is Closer To Us Than The One We Have Selected
long newDepth = ((long)buffer.get(loop*4+1)) & 0xFFFFFFFFL;
if (newDepth < depth) {
choose = buffer.get(loop*4+3); // Select The Closer Object
depth = newDepth; // Store How Far Away It Is
}
}
return (InteractionTarget)( ((Element)elements.get(choose)).getInteractionTarget(Element.TARGET_POSITION) );
}
return null;
}
Camera class:
public void look(GLDrawable drawable) {
Vec3D position = getPerspectivePosition();
if (getProjectionMode() == Camera.MODE_PLANAR_XY) {
drawable.getGLU().gluLookAt(
position.x, position.y, position.z,
focusX, focusY, focusZ,
0, 1, 0);
}
else
drawable.getGLU().gluLookAt(
position.x, position.y, position.z,
focusX, focusY, focusZ,
0, 0, 1); //so that our coordinate system is in the same direction as the simple3d one
//usually 0, 1, 0 is used
}