getScreenCoordinates per Camera

I don't really know if this is the right place for it, but I've updated the code for the "getScreenCoordinates" part of Issue #174 (that is: I've implemented "getScreenCoordinates" in AbstractCamera).

It might be also wise to move "getScreenCoordinates" and "getWorldCoordinates" from LWJGLDisplaySystem to DisplaySystem, since they are renderer independent now - but it's more a design issue, so I left it for you.



Here is the diff with my updates, if you would like to merge them with repository:


Index: src/com/jme/system/lwjgl/LWJGLDisplaySystem.java
===================================================================
RCS file: /cvs/jme/src/com/jme/system/lwjgl/LWJGLDisplaySystem.java,v
retrieving revision 1.35
diff -u -r1.35 LWJGLDisplaySystem.java
--- src/com/jme/system/lwjgl/LWJGLDisplaySystem.java   13 Jan 2006 19:39:57 -0000   1.35
+++ src/com/jme/system/lwjgl/LWJGLDisplaySystem.java   11 Apr 2006 22:35:30 -0000
@@ -352,9 +352,9 @@
     }
 
     // getScreenCoordinates or getWorldCoordinates is called
-    private FloatBuffer tmp_FloatBuffer = BufferUtils.createFloatBuffer(16);
+//    private FloatBuffer tmp_FloatBuffer = BufferUtils.createFloatBuffer(16);
 
-    private IntBuffer tmp_IntBuffer = BufferUtils.createIntBuffer(16);
+//    private IntBuffer tmp_IntBuffer = BufferUtils.createIntBuffer(16);
 
     /**
      * <code>getScreenCoordinates</code> translate world to screen
@@ -365,39 +365,40 @@
      * @return the screen position.
      */
     public Vector3f getScreenCoordinates(Vector3f worldPosition, Vector3f store) {
-        if (store == null)
-            store = new Vector3f();
-
-        // Modelview matrix
-        tmp_FloatBuffer.rewind();
-        GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, tmp_FloatBuffer);
-        float mvArray[][] = new float[4][4];
-        for (int x = 0; x < 4; x++)
-            for (int y = 0; y < 4; y++)
-                mvArray[x][y] = tmp_FloatBuffer.get();
-
-        // Projection_matrix
-        tmp_FloatBuffer.rewind();
-        GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, tmp_FloatBuffer);
-        float prArray[][] = new float[4][4];
-        for (int x = 0; x < 4; x++)
-            for (int y = 0; y < 4; y++)
-                prArray[x][y] = tmp_FloatBuffer.get();
-
-        // Viewport matrix
-        tmp_IntBuffer.rewind();
-        GL11.glGetInteger(GL11.GL_VIEWPORT, tmp_IntBuffer);
-        int[] vpArray = new int[tmp_IntBuffer.capacity()];
-        for (int i = 0; i < vpArray.length; i++) {
-            vpArray[i] = tmp_IntBuffer.get();
-        }
-
-        float[] result = new float[4];
-
-        GLU.gluProject(worldPosition.x, worldPosition.y, worldPosition.z,
-                mvArray, prArray, vpArray, result);
-
-        return store.set(result[0], result[1], result[2]);
+        return getRenderer().getCamera().getScreenCoordinates( worldPosition, store );
+//        if (store == null)
+//            store = new Vector3f();
+//
+//        // Modelview matrix
+//        tmp_FloatBuffer.rewind();
+//        GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, tmp_FloatBuffer);
+//        float mvArray[][] = new float[4][4];
+//        for (int x = 0; x < 4; x++)
+//            for (int y = 0; y < 4; y++)
+//                mvArray[x][y] = tmp_FloatBuffer.get();
+//
+//        // Projection_matrix
+//        tmp_FloatBuffer.rewind();
+//        GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, tmp_FloatBuffer);
+//        float prArray[][] = new float[4][4];
+//        for (int x = 0; x < 4; x++)
+//            for (int y = 0; y < 4; y++)
+//                prArray[x][y] = tmp_FloatBuffer.get();
+//
+//        // Viewport matrix
+//        tmp_IntBuffer.rewind();
+//        GL11.glGetInteger(GL11.GL_VIEWPORT, tmp_IntBuffer);
+//        int[] vpArray = new int[tmp_IntBuffer.capacity()];
+//        for (int i = 0; i < vpArray.length; i++) {
+//            vpArray[i] = tmp_IntBuffer.get();
+//        }
+//
+//        float[] result = new float[4];
+//
+//        GLU.gluProject(worldPosition.x, worldPosition.y, worldPosition.z,
+//                mvArray, prArray, vpArray, result);
+//
+//        return store.set(result[0], result[1], result[2]);
     }
 
     /**


Index: src/com/jme/renderer/Camera.java
===================================================================
RCS file: /cvs/jme/src/com/jme/renderer/Camera.java,v
retrieving revision 1.20
diff -u -r1.20 Camera.java
--- src/com/jme/renderer/Camera.java   13 Jan 2006 19:40:03 -0000   1.20
+++ src/com/jme/renderer/Camera.java   11 Apr 2006 22:06:15 -0000
@@ -502,4 +502,25 @@
      * @return Vector3f The store vector, after storing it's result.
      */
     Vector3f getWorldCoordinates(Vector2f screenPosition, float zPos, Vector3f store );
+
+    /**
+     * Convert world to screen coordinates.
+     *
+     * @param worldPosition
+     *            Vector3f representing the world position
+     * @return Vector3f Screen coordinates, with 0,0 at the bottom left.
+     */
+    Vector3f getScreenCoordinates(Vector3f worldPosition);
+
+    /**
+     * Convert world to screen coordinates.
+     *
+     * @param worldPosition
+     *            Vector3f representing the world position
+     * @param store
+     *            Vector3f The vector to store the result in.
+     * @return Vector3f The store vector, after storing it's result.
+     *            Screen coordinates, with 0,0 at the bottom left.
+     */
+    Vector3f getScreenCoordinates(Vector3f worldPosition, Vector3f store);
 }


Index: src/com/jme/renderer/AbstractCamera.java
===================================================================
RCS file: /cvs/jme/src/com/jme/renderer/AbstractCamera.java,v
retrieving revision 1.35
diff -u -r1.35 AbstractCamera.java
--- src/com/jme/renderer/AbstractCamera.java   13 Jan 2006 19:40:02 -0000   1.35
+++ src/com/jme/renderer/AbstractCamera.java   11 Apr 2006 22:02:25 -0000
@@ -819,6 +819,7 @@
         }
 
         updateMatrices = true;
+        updateSMatrices = true;
     }
 
     /**
@@ -886,6 +887,7 @@
         worldPlane[NEAR_PLANE].setConstant(dirDotLocation + frustumNear);
 
         updateMatrices = true;
+        updateSMatrices = true;
     }
 
     /**
@@ -914,12 +916,19 @@
         return getWorldCoordinates( screenPos, zPos, null );
     }
 
+    /* @see Camera#getScreenCoordinates */
+    public Vector3f getScreenCoordinates(Vector3f worldPos) {
+        return getScreenCoordinates( worldPos, null );
+    }
+
     public abstract Matrix4f getProjectionMatrix();
     public abstract Matrix4f getModelViewMatrix();
 
     private static final Quaternion tmp_quat = new Quaternion();
 
+    private boolean updateSMatrices = true;
     private boolean updateMatrices = true;
+    private final Matrix4f modelViewProjection = new Matrix4f();
     private final Matrix4f modelViewProjectionInverse = new Matrix4f();
 
     /* @see Camera#getWorldCoordinates */
@@ -929,10 +938,14 @@
         {
             store = new Vector3f();
         }
+        if ( updateSMatrices )
+        {
+            modelViewProjection.set( getModelViewMatrix() ).multLocal( getProjectionMatrix() );
+            updateSMatrices = false;
+        }
         if ( updateMatrices )
         {
-            modelViewProjectionInverse.set( getModelViewMatrix() ).multLocal( getProjectionMatrix() );
-            modelViewProjectionInverse.invertLocal();
+            modelViewProjection.invert(modelViewProjectionInverse);
             updateMatrices = false;
         }
         tmp_quat.set(
@@ -944,6 +957,27 @@
         store.x = tmp_quat.x;
         store.y = tmp_quat.y;
         store.z = tmp_quat.z;
+        return store;
+    }
+
+    /* @see Camera#getScreenCoordinates */
+    public Vector3f getScreenCoordinates(Vector3f worldPosition, Vector3f store) {
+        if ( store == null )
+        {
+            store = new Vector3f();
+        }
+        if ( updateSMatrices )
+        {
+            modelViewProjection.set( getModelViewMatrix() ).multLocal( getProjectionMatrix() );
+            updateSMatrices = false;
+        }
+        tmp_quat.set(worldPosition.x, worldPosition.y, worldPosition.z, 1);
+        modelViewProjection.mult( tmp_quat, tmp_quat );
+        tmp_quat.multLocal( 1.0f / tmp_quat.w );
+        store.x = ((tmp_quat.x+1)/2 + viewPortLeft)*getWidth();
+        store.y = ((tmp_quat.y+1)/2 + viewPortBottom)*getHeight();
+        store.z = (tmp_quat.z+1)/2;
+
         return store;
     }
 


Hey, great! Thank you! :slight_smile: I'll get this along with a test into CVS asap.

Thanks irrisor :slight_smile:

test is running fine - committed