Jogl2(より正確には2.0-b58-20120620)とJava7(9番目のリビジョン)を使用しています。ピッキングをしたい:3色の立方体(透視投影)のフレームがあります。
だから私はマウスクリックの場所から光線を構築しようとしています:しかし、gluUnprojectを呼び出すと、常にポイント(O、O、O)を取得します。
残念ながら、この既存の投稿は私を助けることができません。そして、これは私の状況では足りないようです。
これが私のAppLauncher.javaです
package com.gmail.bernabe.laurent.java_opengl.picking_test;
import com.gmail.bernabe.laurent.java_opengl.picking_test.views.MainFrame;
public class AppLauncher {
public static void main(String[] args) {
new MainFrame().setVisible(true);
}
}
MainFrame.java
package com.gmail.bernabe.laurent.java_opengl.picking_test.views;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
import com.jogamp.opengl.util.FPSAnimator;
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("A jogl picking test");
setSize(new Dimension(640, 510));
setLocationRelativeTo(null);
GLCanvas glCanvas = new GLCanvas();
add(glCanvas);
TheGLEventListener glListener = new TheGLEventListener();
glCanvas.addGLEventListener(glListener);
glCanvas.addMouseListener(glListener);
final FPSAnimator animator = new FPSAnimator(glCanvas, 120);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
animator.stop();
System.exit(0);
}
});
animator.start();
}
private static final long serialVersionUID = 4972092015545764168L;
}
TheGLEventListener.java
package com.gmail.bernabe.laurent.java_opengl.picking_test.views;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.gl2.GLUgl2;
import com.gmail.bernabe.laurent.java_opengl.picking_test.logic.GLLittleCube;
import com.gmail.bernabe.laurent.java_opengl.picking_test.logic.Ray;
public class TheGLEventListener implements GLEventListener,MouseListener {
@Override
public void init(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glClearColor(0.67f, 0.16f, 0.51f, 0.0f);
}
@Override
public void dispose(GLAutoDrawable drawable) {
// TODO Auto-generated method stub
}
@Override
public void display(GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
if (pendingEvent != null){
if (pendingEvent.getId() == MouseEvent.MOUSE_CLICKED) {
Ray.fromMouseCoords(pendingEvent.getX(), pendingEvent.getY(), gl);
pendingEvent = null;
}
}
glu.gluLookAt(
0.0f, 0.0f, 9.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f
);
drawScene(gl);
}
private void drawScene(GL2 gl) {
gl.glPushMatrix();
gl.glTranslatef(-3.0f, +1.0f, +2.0f);
GLLittleCube.draw(gl);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef(-2.0f, +3.0f, -4.0f);
GLLittleCube.draw(gl);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef(+1.0f, -2.0f, +3.0f);
GLLittleCube.draw(gl);
gl.glPopMatrix();
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
GL2 gl = drawable.getGL().getGL2();
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(60.0, width * 1.0f / height, 0.1, 20);
gl.glMatrixMode(GL2.GL_MODELVIEW);
}
private GLU glu = new GLUgl2();
@Override
public void mouseClicked(MouseEvent e) {
pendingEvent = e;
}
@Override
public void mousePressed(MouseEvent e) {
// Not used
}
@Override
public void mouseReleased(MouseEvent e) {
// Not used
}
@Override
public void mouseEntered(MouseEvent e) {
// Not used
}
@Override
public void mouseExited(MouseEvent e) {
// Not used
}
private MouseEvent pendingEvent;
}
GLLittleCube.java
package com.gmail.bernabe.laurent.java_opengl.picking_test.logic;
import javax.media.opengl.GL2;
public class GLLittleCube {
public static void draw(GL2 gl){
gl.glBegin(GL2.GL_QUADS);
//FRONT face (BLUE)
gl.glColor3f(0.0f, 0.13f, 0.66f);
gl.glVertex3f(-1.0f, -1.0f, +1.0f);
gl.glVertex3f(+1.0f, -1.0f, +1.0f);
gl.glVertex3f(+1.0f, +1.0f, +1.0f);
gl.glVertex3f(-1.0f, +1.0f, +1.0f);
//BACK face (GREEN)
gl.glColor3f(0.07f, 0.43f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glVertex3f(+1.0f, -1.0f, -1.0f);
gl.glVertex3f(+1.0f, +1.0f, -1.0f);
gl.glVertex3f(-1.0f, +1.0f, -1.0f);
//LEFT face (RED)
gl.glColor3f(0.7f, 0.0f, 0.0f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glVertex3f(-1.0f, +1.0f, -1.0f);
gl.glVertex3f(-1.0f, +1.0f, +1.0f);
gl.glVertex3f(-1.0f, -1.0f, +1.0f);
//RIGHT face (ORANGE)
gl.glColor3f(1.0f, 0.45f, 0.05f);
gl.glVertex3f(+1.0f, -1.0f, -1.0f);
gl.glVertex3f(+1.0f, +1.0f, -1.0f);
gl.glVertex3f(+1.0f, +1.0f, +1.0f);
gl.glVertex3f(+1.0f, -1.0f, +1.0f);
//TOP face (WHITE)
gl.glColor3f(0.97f, 0.90f, 0.95f);
gl.glVertex3f(-1.0f, +1.0f, -1.0f);
gl.glVertex3f(+1.0f, +1.0f, -1.0f);
gl.glVertex3f(+1.0f, +1.0f, +1.0f);
gl.glVertex3f(-1.0f, +1.0f, +1.0f);
//BOTTOM face (YELLOW)
gl.glColor3f(0.93f, 0.87f, 0.07f);
gl.glVertex3f(-1.0f, -1.0f, -1.0f);
gl.glVertex3f(+1.0f, -1.0f, -1.0f);
gl.glVertex3f(+1.0f, -1.0f, +1.0f);
gl.glVertex3f(-1.0f, -1.0f, +1.0f);
gl.glEnd();
}
}
Ray.java
package com.gmail.bernabe.laurent.java_opengl.picking_test.logic;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.gl2.GLUgl2;
public class Ray {
private Vector3f origin, direction;
public Ray(Vector3f origin, Vector3f direction) {
this.origin = origin;
this.direction = direction;
}
public Vector3f getOrigin() {
return origin;
}
public Vector3f getDirection() {
return direction;
}
public static Ray fromMouseCoords(int mouseX, int mouseY, GL2 gl){
IntBuffer viewport;
FloatBuffer modelViewMatrix;
FloatBuffer projectionMatrix;
FloatBuffer objectPos;
FloatBuffer winZ;
ByteBuffer tempViewport = ByteBuffer.allocateDirect(4*4);
tempViewport.order(ByteOrder.nativeOrder());
viewport = tempViewport.asIntBuffer();
ByteBuffer tempModelView = ByteBuffer.allocateDirect(16*4);
tempModelView.order(ByteOrder.nativeOrder());
modelViewMatrix = tempModelView.asFloatBuffer();
ByteBuffer tempProjection = ByteBuffer.allocateDirect(16*4);
tempProjection.order(ByteOrder.nativeOrder());
projectionMatrix = tempProjection.asFloatBuffer();
ByteBuffer tempObjectPos = ByteBuffer.allocateDirect(3*4);
tempObjectPos.order(ByteOrder.nativeOrder());
objectPos = tempObjectPos.asFloatBuffer();
ByteBuffer tempWinZ = ByteBuffer.allocateDirect(1*4);
tempWinZ.order(ByteOrder.nativeOrder());
winZ = tempWinZ.asFloatBuffer();
gl.glGetIntegerv(GL2.GL_VIEWPORT, viewport);
gl.glGetFloatv(GL2.GL_MODELVIEW, modelViewMatrix);
gl.glGetFloatv(GL2.GL_PROJECTION, projectionMatrix);
float winY = viewport.get(3) * 1.0f - mouseY;
float winX = mouseX * 1.0f;
gl.glReadPixels(mouseX, mouseY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, winZ);
glu.gluUnProject(winX, winY, 0.0f, modelViewMatrix, projectionMatrix, viewport, objectPos);
Vector3f tempOrigin = new Vector3f(objectPos.get(0), objectPos.get(1), objectPos.get(2));
glu.gluUnProject(winX, winY, winZ.get(0), modelViewMatrix, projectionMatrix, viewport, objectPos);
Vector3f tempDest = new Vector3f(objectPos.get(0), objectPos.get(1), objectPos.get(2));
Vector3f tempDirection = tempDest.clone().sub(tempOrigin).normalize();
/////////////////////////////////
System.err.println("origin : "+tempOrigin);
System.err.println("dest : "+tempDest);
System.err.println("direction : "+tempDirection);
System.err.println();
/////////////////////////////
return new Ray(tempOrigin, tempDirection);
}
private static GLU glu = new GLUgl2();
}
最後に、Vector3f.java
package com.gmail.bernabe.laurent.java_opengl.picking_test.logic;
public class Vector3f {
private float x, y, z;
public Vector3f(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
public Vector3f(){
this(0.0f, 0.0f, 0.0f);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getZ() {
return z;
}
public Vector3f clone(){
return new Vector3f(x, y, z);
}
/**
* With side effect !!!
* @param other
* @return
*/
public Vector3f add(Vector3f other){
x += other.x;
y += other.y;
z += other.z;
return this;
}
/**
* With side effect !!!
* @param other
* @return
*/
public Vector3f sub(Vector3f other){
x -= other.x;
y -= other.y;
z -= other.z;
return this;
}
public double length(){
return Math.sqrt(x*x + y*y + z*z);
}
/**
* With side effect !!!
* @return
*/
public Vector3f normalize(){
double norm = length();
if (norm > 1e-12f){
x /= norm;
y /= norm;
z /= norm;
}
return this;
}
public double dot(Vector3f other){
return x*other.x + y*other.y + z*other.z;
}
/**
* Without any side effect !!!
* @param other
* @return
*/
public Vector3f cross(Vector3f other){
float tempX, tempY, tempZ;
tempX = y*other.z - z*other.y;
tempY = z*other.x - x*other.z;
tempZ = x*other.y - y*other.x;
return new Vector3f(tempX, tempY, tempZ);
}
public String toString(){
return String.format("Vector3f(x=%f, y=%f, z=%f)", x,y,z);
}
}
それで、何が問題なのですか?