I am using picking to find out if there is an object in front of my main character. So, I select a region on the screen(where my character is), and I find the depths of all the objects I want it this region. If the smallest depth does not belong to my character, then this means that another object is closer to me (the screen), and I act accordingly.
This technique works great, apart from the case when the camera is really close to my character. I do not mean inside it, where maybe I could understand if it got confused, I mean very close to it. In this case, it does not detect the depth of my character, and goes to the next one. After I printed out the current depth of my character for each frame I was getting close to it, I found out that it stopped when reaching somewhere close to -2147471104. Which is very close to the minimum int value, -2147483648. So I though that this must be why.
The code I use is to start picking:
private void startPicking3D(int xHead, int yHead, int xSide, int ySide){
// The selection buffer
selBuffer = ByteBuffer.allocateDirect(1024).order(ByteOrder.nativeOrder()).asIntBuffer();
IntBuffer vpBuffer = ByteBuffer.allocateDirect(64).order(ByteOrder.nativeOrder()).asIntBuffer();
// The size of the viewport. [0] Is <x>, [1] Is <y>, [2] Is <width>, [3] Is <height>
int[] viewport = new int[4];
// The number of "hits" (objects within the pick area).
// Get the viewport info
GL11.glGetInteger(GL11.GL_VIEWPORT, vpBuffer);
vpBuffer.get(viewport);
// Set the buffer that OpenGL uses for selection to our buffer
GL11.glSelectBuffer(selBuffer);
// Change to selection mode
GL11.glRenderMode(GL11.GL_SELECT);
// Initialize the name stack (used for identifying which object was selected)
GL11.glInitNames();
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
// create 5x5 pixel picking region near cursor location */
GLU.gluPickMatrix( (float) xHead, (float) yHead, xSide, ySide, IntBuffer.wrap(viewport));
GLU.gluPerspective(65.0f,
(float)1280/(float)800,
0.1f,
150.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
}
The code to stop picking:
public void stopPicking(){
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
hits = 0;
hits = GL11.glRenderMode(GL11.GL_RENDER);
}
And the the code for finding out selected object:
public int getSelectedEntity(){
int[] buffer = new int[256];
int EntityID = -1;
selBuffer.get(buffer);
// Objects Were Drawn Where The Mouse Was
if (hits > 0) {
// If There Were More Than 0 Hits
EntityID = buffer[3]; // Make Our Selection The First Object
int depth = buffer[1]; // Store How Far Away It Is
for (int i = 1; i < hits; i++) {
// Loop Through All The Detected Hits
// If This Object Is Closer To Us Than The One We Have Selected
if (buffer[i * 4 + 1] < (int) depth) {
EntityID = buffer[i * 4 + 3]; // Select The Closest Object
depth = buffer[i * 4 + 1]; // Store How Far Away It Is
}
}
}
return EntityID;
}
My questions are:
Are these big depth values generally normal?
If yes, then should I use long? But how, considering that selBuffer is declared as IntBuffer and glSelectBuffer requires IntBuffer only.