changeset 5213:105b4c1ce770

RT-30637: used proper near/far clipping planes for default perspective camera.
author Pavel Safrata <pavel.safrata@oracle.com>
date Tue, 01 Oct 2013 10:25:57 +0100
parents d049142f7145
children cd993475e253
files apps/toys/FX8-3DFeatures/src/fx83dfeatures/NearAndFarClipTest.java modules/graphics/src/main/java/com/sun/javafx/geom/PickRay.java modules/graphics/src/main/java/javafx/scene/Node.java modules/graphics/src/main/java/javafx/scene/PerspectiveCamera.java modules/graphics/src/test/java/javafx/scene/Mouse3DTest.java
diffstat 5 files changed, 80 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/apps/toys/FX8-3DFeatures/src/fx83dfeatures/NearAndFarClipTest.java	Tue Oct 01 09:50:59 2013 +0200
+++ b/apps/toys/FX8-3DFeatures/src/fx83dfeatures/NearAndFarClipTest.java	Tue Oct 01 10:25:57 2013 +0100
@@ -25,9 +25,11 @@
 package fx83dfeatures;
 
 import javafx.application.Application;
+import javafx.event.EventHandler;
 import javafx.scene.Group;
 import javafx.scene.PerspectiveCamera;
 import javafx.scene.Scene;
+import javafx.scene.input.MouseEvent;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Stage;
@@ -52,7 +54,7 @@
         final double farClipDistance = focalLength * FAR + eyePositionZ;
         final double nearClipDistanceOffset = Math.abs(nearClipDistance * OFFSET_PERCENT);
         final double farClipDistanceOffset = Math.abs(farClipDistance * OFFSET_PERCENT);
-        
+
         System.out.println("In scene coordinate: focalLength = " + focalLength
                 + ", nearClipDistance = " + nearClipDistance
                 + ", nearClipDistanceOffset = " + nearClipDistanceOffset
@@ -62,26 +64,31 @@
         Rectangle insideRect = new Rectangle(220, 220, Color.GREEN);
         insideRect.setLayoutX(140);
         insideRect.setLayoutY(140);
+        insideRect.setId("Green");
 
         Rectangle insideNearClip = new Rectangle(16, 16, Color.BLUE);
         insideNearClip.setLayoutX(242);
         insideNearClip.setLayoutY(242);
         insideNearClip.setTranslateZ(nearClipDistance + nearClipDistanceOffset);
+        insideNearClip.setId("Blue");
 
         Rectangle outsideNearClip = new Rectangle(16, 16, Color.YELLOW);
         outsideNearClip.setLayoutX(242);
         outsideNearClip.setLayoutY(242);
         outsideNearClip.setTranslateZ(nearClipDistance - nearClipDistanceOffset);
+        outsideNearClip.setId("Yellow");
 
         Rectangle insideFarClip = new Rectangle(3000, 3000, Color.RED);
         insideFarClip.setTranslateX(-1250);
         insideFarClip.setTranslateY(-1250);
         insideFarClip.setTranslateZ(farClipDistance - farClipDistanceOffset);
+        insideFarClip.setId("Red");
 
         Rectangle outsideFarClip = new Rectangle(4000, 4000, Color.CYAN);
         outsideFarClip.setTranslateX(-1750);
         outsideFarClip.setTranslateY(-1750);
         outsideFarClip.setTranslateZ(farClipDistance + farClipDistanceOffset);
+        outsideFarClip.setId("Cyan");
 
         Group root = new Group();
 
@@ -90,6 +97,13 @@
 
         // Intentionally set depth buffer to false to reduce test complexity
         Scene scene = new Scene(root, WIDTH, HEIGHT, false);
+        scene.setOnMousePressed(new EventHandler<MouseEvent>() {
+            @Override public void handle(MouseEvent event) {
+                System.out.println("Clicked: " + event.getTarget());
+            }
+        });
+
+
         PerspectiveCamera camera = new PerspectiveCamera();
         camera.setFieldOfView(FOV);
         camera.setNearClip(NEAR);
@@ -99,7 +113,7 @@
     }
 
     @Override public void start(Stage stage) {
-        Scene scene = createClipPlanes(stage); 
+        Scene scene = createClipPlanes(stage);
         scene.setFill(Color.GRAY);
         stage.setScene(scene);
         stage.sizeToScene();
--- a/modules/graphics/src/main/java/com/sun/javafx/geom/PickRay.java	Tue Oct 01 09:50:59 2013 +0200
+++ b/modules/graphics/src/main/java/com/sun/javafx/geom/PickRay.java	Tue Oct 01 10:25:57 2013 +0100
@@ -84,8 +84,8 @@
             eye.set(halfViewWidth, halfViewHeight, -distanceZ);
         }
 
-        pickRay.nearClip = nearClip * (direction.length() / distanceZ);
-        pickRay.farClip = farClip * (direction.length() / distanceZ);
+        pickRay.nearClip = nearClip * (direction.length() / (fixedEye ? distanceZ : 1.0));
+        pickRay.farClip = farClip * (direction.length() / (fixedEye ? distanceZ : 1.0));
 
         pickRay.transform(cameraTransform);
 
--- a/modules/graphics/src/main/java/javafx/scene/Node.java	Tue Oct 01 09:50:59 2013 +0200
+++ b/modules/graphics/src/main/java/javafx/scene/Node.java	Tue Oct 01 10:25:57 2013 +0100
@@ -4874,7 +4874,7 @@
         final double minDistance = pickRay.getNearClip();
         final double maxDistance = pickRay.getFarClip();
         if (tmin < minDistance) {
-            if (tmax >= minDistance && tmax <= maxDistance) {
+            if (tmax >= minDistance) {
                 // we are inside bounds
                 return 0.0;
             } else {
--- a/modules/graphics/src/main/java/javafx/scene/PerspectiveCamera.java	Tue Oct 01 09:50:59 2013 +0200
+++ b/modules/graphics/src/main/java/javafx/scene/PerspectiveCamera.java	Tue Oct 01 10:25:57 2013 +0100
@@ -212,9 +212,7 @@
                 getViewWidth(), getViewHeight(),
                 getFieldOfView(), isVerticalFieldOfView(),
                 getCameraTransform(),
-                //TODO: use actual clips always after rendering uses them
-                fixedEyeAtCameraZero ? getNearClip() : 0.0,
-                fixedEyeAtCameraZero ? getFarClip() : Double.POSITIVE_INFINITY,
+                getNearClip(), getFarClip(),
                 pickRay);
     }
 
--- a/modules/graphics/src/test/java/javafx/scene/Mouse3DTest.java	Tue Oct 01 09:50:59 2013 +0200
+++ b/modules/graphics/src/test/java/javafx/scene/Mouse3DTest.java	Tue Oct 01 10:25:57 2013 +0100
@@ -112,11 +112,14 @@
         scene(group(), cam, true);
         cam.impl_updatePeer();
         PickRay pickRay = cam.computePickRay(100, 200, null);
-        assertEquals(0.0, pickRay.getNearClip(), 0.01);
-        assertTrue(Double.isInfinite(pickRay.getFarClip()));
-        //TODO: replace the conditions by the following:
-//        assertEquals(104.39, pickRay.getNearClip(), 0.01);
-//        assertEquals(208.78, pickRay.getFarClip(), 0.01);
+
+        double xd = PERSPECTIVE_CAMERA_X - 100;
+        double yd = PERSPECTIVE_CAMERA_Y - 200;
+        double pd = Math.sqrt(xd * xd + yd * yd);
+        double len = Math.sqrt(PERSPECTIVE_CAMERA_Z * PERSPECTIVE_CAMERA_Z + pd * pd);
+
+        assertEquals(len * 100, pickRay.getNearClip(), 0.01);
+        assertEquals(len * 200, pickRay.getFarClip(), 0.01);
     }
 
     @Test
@@ -2077,6 +2080,56 @@
                 21, NOFACE, null);
     }
 
+    @Test
+    public void shouldIgnoreRectangleCloserThanNearClip() {
+
+        Camera cam = new PerspectiveCamera();
+        cam.setNearClip(0.2);
+        double nearClip = PERSPECTIVE_CAMERA_Z * 0.8;
+
+        Rectangle r1 = rect().handleMove(me);
+        r1.setTranslateX(PERSPECTIVE_CAMERA_X - 50);
+        r1.setTranslateY(PERSPECTIVE_CAMERA_Y - 50);
+        r1.setTranslateZ(nearClip - 0.1);
+        Rectangle r2 = rect().handleMove(sme);
+        r2.setTranslateX(PERSPECTIVE_CAMERA_X - 50);
+        r2.setTranslateY(PERSPECTIVE_CAMERA_Y - 50);
+        r2.setTranslateZ(nearClip + 0.1);
+
+        Scene s = scene(group(r1, r2), cam, true);
+
+        s.impl_processMouseEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_MOVED, 540, 440));
+
+        assertNull(me.event);
+        assertNotNull(sme.event);
+    }
+
+    @Test
+    public void shouldIgnoreRectangleFartherThanFarClip() {
+
+        Camera cam = new PerspectiveCamera();
+        cam.setNearClip(0.1);
+        cam.setFarClip(0.3);
+        double far = PERSPECTIVE_CAMERA_Z * 0.7;
+
+        Rectangle r = rect().handleMove(me);
+        r.setTranslateX(PERSPECTIVE_CAMERA_X - 50);
+        r.setTranslateY(PERSPECTIVE_CAMERA_Y - 50);
+        r.setTranslateZ(far - 0.1);
+
+        Scene s = scene(group(r), cam, true);
+
+        s.impl_processMouseEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_MOVED, 540, 440));
+        assertNotNull(me.event);
+
+        me.clear();
+        r.setTranslateZ(far + 0.1);
+        s.impl_processMouseEvent(MouseEventGenerator.generateMouseEvent(
+                MouseEvent.MOUSE_MOVED, 540, 440));
+        assertNull(me.event);
+    }
 
     /*****************  Scenegraph-generated events ********************/
 
@@ -2353,6 +2406,8 @@
         PerspectiveCamera cam = new PerspectiveCamera(fixedEye);
         // this field of view makes camera Z position to be -1000
         cam.setFieldOfView(43.60281897);
+        // this makes the near clip to be also at -1000
+        cam.setNearClip(0.0);
         return cam;
     }