Translating Mouse Coordinates from 2D to 3D

Sorry if this has been asked before, but if it has I can’t find it!

I’d like to be able to translate from a 2D coordinate on the surface of a canvas into a 3D coordinate within the scene. I realise a single point on the surface corresponds to a line of infinite length in 3D space, but my Z-coordinate is fixed, so there’s just a single point I’m interested in.

To explain more graphically, I have a turret that I want to pan around to aim wherever the mouse is. The turret always aims at the same Z-depth as itself, but its angle can change.

I’ve seen examples of this using an orthographic view, but I would like my scene to be fully 3D and not viewed-from-above.

Is it possible to find the x and y coordinates under the mouse cursor, if the z coordinate is known? If so, could anyone offer an example of how this can be done?

Thanks

What information do you have readily available about your projection transformation?

Do you have your full projection matrix?

Do you know the 8 corners of your frustum, or the 6 planes of it?

Do you know your near/far planes + horizontal and vertical fov?

I can probably help you if you know any of those. I find it quickest and easiest to do if you have the frustum corners cached somewhere.

If you use glu, you could also try gluUnproject().

JW

I defined my perspective pretty simply, so I don’t have that level of detail sitting around as variables already. Since I had to calculate anyway, I figured I’d go the GLU route, and that works fine!

Thanks for the tip!

Hello,

I’m new member and as well new to JOGL.
Please help me understand 3D world coordinates for a mouse click using “glu.gluUnProject”.

I followed an example from “Red Book”
( link http://www.java-tips.org/other-api-tips/jogl/how-to-use-gluunproject-in-jogl.html )

To the existing program,
I added 4 points .
Point 1 ( 0, 0, 0 ) Red colored
Point 2 ( 1, 0, 0 ) Green colored
Point 3 ( 0, 0, 1 ) Blue colored
Point 4 ( 1, 0, 1 ) Yellow colored

When I mouse clicked (mouse x=250 and y=250) on Point 1 ( 0, 0, 0 ) Red Colored,
I would like to get world co-ordinates as 0.0, 0.0, 0.0
similarly,

When I mouse clicked on Point 2 ( 1, 0, 0 ) Green Colored,
I would like to get world co-ordinates as 1.0, 0.0, 0.0
When I mouse clicked on Point 3 ( 0, 0, 1 ) Blue Colored,
I would like to get world co-ordinates as 0.0, 0.0, 1.0
When I mouse clicked on Point 3 ( 1, 0, 1 ) Yellow Colored,
I would like to get world co-ordinates as 1.0, 0.0, 1.0

Please help me using proper value of “z”, third parameter on function
glu.gluUnProject((double) x, (double) realy, z, mvmatrix, 0, projmatrix, 0, viewport, 0, wcoord, 0);

Please note:
I used " glu.gluLookAt(0,1,4,0,0,0,0,1,0); "
and a function to draw points which are highlighted in Red color

import java.awt.event.*;

import javax.media.opengl.;
import javax.media.opengl.glu.
;
import javax.swing.*;

/**

  • When the left mouse button is pressed, this program reads the mouse position
  • and determines two 3D points from which it was transformed. Very little is
  • displayed.
  • @author Kiet Le (Java port)
    */
    public class unproject
    extends JFrame
    implements GLEventListener, KeyListener, MouseListener
    {
    private GLU glu;
    private GLCapabilities caps;
    private GLCanvas canvas;
    private MouseEvent mouse;

public unproject()
{
super(“unproject”);

caps = new GLCapabilities();
canvas = new GLCanvas(caps);
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
canvas.addMouseListener(this);

getContentPane().add(canvas);

}

public void run()
{
setSize(500, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
canvas.requestFocusInWindow();
}

public static void main(String[] args)
{
new unproject().run();
}

public void init(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
glu = new GLU();
}

public void display(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();

//gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
glu.gluLookAt(0,1,4,0,0,0,0,1,0);

//Draw Points
drawPoints(drawable);


int viewport[] = new int[4];
double mvmatrix[] = new double[16];
double projmatrix[] = new double[16];
int realy = 0;// GL y coord pos
double wcoord[] = new double[4];// wx, wy, wz;// returned xyz coords

if (mouse != null)
{
  int x = mouse.getX(), y = mouse.getY();
  System.out.println("\nMouse X = "+x+"  Mouse Y = "+y);
  switch (mouse.getButton()) {
    case MouseEvent.BUTTON1:
      gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
      gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
      gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);
      /* note viewport[3] is height of window in pixels */
      realy = viewport[3] - (int) y - 1;
      System.out.println("Coordinates at cursor are (" + x + ", " + realy);
      glu.gluUnProject((double) x, (double) realy, 0.0, //
          mvmatrix, 0,
          projmatrix, 0,
          viewport, 0,
          wcoord, 0);
      System.out.println("World coords at z=0.0 are ( " //
                         + wcoord[0] + ", " + wcoord[1] + ", " + wcoord[2]
                         + ")");
      glu.gluUnProject((double) x, (double) realy, 1.0, //
          mvmatrix, 0,
          projmatrix, 0,
          viewport, 0,
          wcoord, 0);
      System.out.println("World coords at z=1.0 are (" //
                         + wcoord[0] + ", " + wcoord[1] + ", " + wcoord[2]
                         + ")");
      break;
    case MouseEvent.BUTTON2:
      break;
    default:
      break;
  }
}

gl.glFlush();

}

public void drawPoints(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
gl.glColor3f(1.0f,0.0f,0.0f);
gl.glPointSize(5.0f);
gl.glBegin(GL.GL_POINTS);
gl.glVertex3f(0.0f,0.0f,0.0f);
gl.glColor3f(0.0f,1.0f,0.0f);
gl.glVertex3f(1.0f,0.0f,0.0f);
gl.glEnd();
gl.glPointSize(1.0f);

    gl.glColor3f(0.0f,0.0f,1.0f);
    gl.glPointSize(5.0f);
    gl.glBegin(GL.GL_POINTS);
    gl.glVertex3f(0.0f,0.0f,1.0f);
    gl.glColor3f(1.0f,1.0f,0.0f);
    gl.glVertex3f(1.0f,0.0f,1.0f);
    gl.glEnd();
    gl.glPointSize(1.0f);

}

/* Change these values for a different transformation */
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h)
{
GL gl = drawable.getGL();

gl.glViewport(0, 0, w, h);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(45.0, (float) w / (float) h, 1.0, 100.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();

}

public void displayChanged(GLAutoDrawable drawable, boolean modeChanged,
boolean deviceChanged)
{
}

public void keyTyped(KeyEvent key)
{
}

public void keyPressed(KeyEvent key)
{

switch (key.getKeyCode()) {
  case KeyEvent.VK_ESCAPE:
    System.exit(0);
    break;

  default:
    break;
}

}

public void keyReleased(KeyEvent key)
{
}

public void mouseClicked(MouseEvent e)
{
}

public void mousePressed(MouseEvent e)
{
mouse = e;
canvas.display();
}

public void mouseReleased(MouseEvent e)
{
}

public void mouseEntered(MouseEvent e)
{
}

public void mouseExited(MouseEvent e)
{
}

}

Nick