Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  Transform mouse coordinates to world XZ coordinates  (Read 797 times)
0 Members and 2 Guests are viewing this topic.
Offline Grand Poeba

Full Member
**

Posts: 143



« on: 2011-11-21 12:35:23 »

Hi

I am currently working on a some sort of editor. The terrain of this editor is a map built out of tiles (squares).
When i click my GLJPanel i sent a mouseevent because I want to check if I click on a tile.

So basicly I want to convert my X and Y mouse coordinate to Coordinate in the XZ plane (since Y axis is the one pointing up).

So far I tried to do this using glu.gluUnProject but i have no success doing so

During init methode of GLEventListener
1  
2  
3  
        this.viewport = IntBuffer.allocate(4);                                  // Where The Viewport Values Will Be Stored
       this.modelview = FloatBuffer.allocate(16);                              // Where The 16 Doubles Of The Modelview Matrix Are To Be Stored
       this.projectionview = FloatBuffer.allocate(16);                         // Where The 16 Doubles Of The Projection Matrix Are To Be Stored


Whenever I reshape my window I update the buffers
1  
2  
        gl.glGetIntegerv(GL2.GL_VIEWPORT, this.viewport);
        gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX, this.projectionview);


Every time a frame is drawn i update modelview buffer in display method
1  
        gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX, this.modelview);


This is the code i execute when i want to convert the mouse to XZ plane coordinates
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
        float winX, winY;                                                         // Holds Our X, Y and Z Coordinates

        winX = (float)this.pickX;                                               // Holds The Mouse X Coordinate
       winY = (float)this.pickY;                                               // Holds The Mouse Y Coordinate
       winY = (float)this.viewport.get(3) - winY - 1;                   // Subtract The Current Mouse Y Coordinate From The Screen Height.
               
        FloatBuffer projectedPositions = FloatBuffer.allocate(3);

        boolean succes = new GLU().gluUnProject(winX, winY, 0.0f, this.modelview, this.projectionview, this.viewport, projectedPositions);
       
        System.out.println(projectedPositions.get(0)+" "+projectedPositions.get(1)+" "+projectedPositions.get(2)+" "+succes);


Am I using the wrong method or am I passing along the wrong arguments?


When i see at least 10 tiles on my screen, each tile = 1.0f x 1.0f the difference between most left and most right tile on my screen is maybe 0.1f so something is obviously going wrong

Thx for any help
Offline theagentd

JGO Wizard
****

Posts: 1392
Medals: 88



« Reply #1 on: 2011-11-21 21:52:01 »

If you're doing this in 3D:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
private FloatBuffer getMousePosition(int mouseX, int mouseY) {
    IntBuffer viewport = BufferUtils.createIntBuffer(16);
    FloatBuffer modelview = BufferUtils.createFloatBuffer(16);
    FloatBuffer projection = BufferUtils.createFloatBuffer(16);
    FloatBuffer winZ = BufferUtils.createFloatBuffer(1);
    FloatBuffer position = BufferUtils.createFloatBuffer(3);

    GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelview);
    GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projection);
    GL11.glGetInteger(GL11.GL_VIEWPORT, viewport);

    GL11.glReadPixels(mouseX, mouseY, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, winZ);

    if (winZ.get(0) == 1) {
        return null;
    }

    GLU.gluUnProject(mouseX, mouseY, winZ.get(), modelview, projection, viewport, position);

    return position;
}


but you're using 2D, aren't you? It's easier to just do the math to find where your mouse is in the game world. This requires you to keep track of the transformations that you do, but it should still be faster than doing that many OpenGL calls.

There is no god.
Offline Grand Poeba

Full Member
**

Posts: 143



« Reply #2 on: 2011-11-23 04:03:46 »

I have enabled GL.GL_DETPH and changed converting code to

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
        winX = (float)this.pickX;                                               // Holds The Mouse X Coordinate
       winY = (float)this.pickY;                                               // Holds The Mouse Y Coordinate
       winY = (float)this.viewport.get(3) - winY;                              // Subtract The Current Mouse Y Coordinate From The Screen Height.
                       
       
        FloatBuffer fb = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        gl.glReadPixels((int)winX, (int)winY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, fb);
        fb.rewind();
       
        System.out.println("Coordinates at cursor are (" + winX + ", " + winY+")");
       
        FloatBuffer projectedPositions = FloatBuffer.allocate(3);
        new GLU().gluUnProject(winX, winY, fb.get(0), //
              this.modelview, this.projectionview, this.viewport, projectedPositions);
       
         System.out.println("World coords at z="+fb.get(0)+" are ( " //
                            + projectedPositions.get(0)+" "+projectedPositions.get(1)+" "+projectedPositions.get(2)
                             + ")");


The results are much realistic now, but the there is still deviation, except for points near the center of my screen.
Should i also update the projection matrix each from or is modelmatrix enough?

thx
Games published by our own members! Go get 'em!
Offline Grand Poeba

Full Member
**

Posts: 143



« Reply #3 on: 2011-11-23 04:11:04 »

Ah nevermind if found the solution Smiley

I forgot to reset the camera to its place after drawing the scene before doing the picking

The coordinates are correct now when i click on a square i draw. Thx for any help
Offline theagentd

JGO Wizard
****

Posts: 1392
Medals: 88



« Reply #4 on: 2011-11-23 04:54:39 »

Great that you got it working. Remember that calling glReadPixels forces the processor to wait for the graphics card to render the scene. It's a very good idea to read pixels of the last frame instead, or at least do the read at the beginning of the next frame before clearing it. You can also do it asynchronously, but I don't know exactly how to do that though.

There is no god.
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.085 seconds with 20 queries.