1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene; 27 28 import com.sun.javafx.FXUnit; 29 import com.sun.javafx.geom.Vec3d; 30 import com.sun.javafx.geom.transform.Affine3D; 31 import com.sun.javafx.geom.transform.GeneralTransform3D; 32 import com.sun.javafx.sg.prism.NGNode; 33 import com.sun.javafx.sg.prism.NGParallelCamera; 34 import com.sun.javafx.sg.prism.NGPerspectiveCamera; 35 import com.sun.javafx.test.TransformHelper; 36 import com.sun.javafx.tk.Toolkit; 37 import javafx.scene.transform.NonInvertibleTransformException; 38 import javafx.stage.Stage; 39 import org.junit.Rule; 40 import org.junit.Test; 41 42 import static org.junit.Assert.*; 43 44 public class CameraTest { 45 46 @Rule 47 public FXUnit fx = new FXUnit(); 48 49 static final GeneralTransform3D DEFAULT_PROJVIEW_TX; 50 static { 51 GeneralTransform3D expected = new GeneralTransform3D(); 52 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 53 final double tanOfHalfFOV = Math.tan(Math.toRadians(30) / 2.0); 54 Affine3D view = new Affine3D(); 55 final double scale = 2.0 * tanOfHalfFOV / 200; 56 view.setToTranslation(-tanOfHalfFOV * 1.5, tanOfHalfFOV, 0.0); 57 view.translate(0, 0, -1); 58 view.rotate(Math.PI, 1, 0, 0); 59 view.scale(scale, scale, scale); 60 expected.mul(view); 61 DEFAULT_PROJVIEW_TX = expected; 62 } 63 64 /** 65 * Test of setNearClip method, of class Camera. 66 */ 67 @Test 68 public void testSetNearClip() { 69 Camera camera = new PerspectiveCamera(); 70 camera.setTranslateZ(-10); 71 camera.setNearClip(10); 72 73 assertEquals(10, camera.getNearClip(), 1e-3); 74 assertEquals(90, camera.getFarClipInScene(), 1e-3); 75 assertEquals(0, camera.getNearClipInScene(), 1e-3); 76 } 77 78 /** 79 * Test of getNearClipInScene method, of class Camera. 80 */ 81 @Test 82 public void testGetNearClipInScene() { 83 Camera camera = new PerspectiveCamera(); 84 camera.setTranslateZ(-10); 85 86 assertEquals(-9.9, camera.getNearClipInScene(), 1e-3); 87 } 88 89 /** 90 * Test of setFarClip method, of class Camera. 91 */ 92 @Test 93 public void testSetFarClip() { 94 Camera camera = new PerspectiveCamera(); 95 camera.setTranslateZ(-10); 96 camera.setFarClip(200); 97 98 assertEquals(200, camera.getFarClip(), 1e-3); 99 assertEquals(-9.9, camera.getNearClipInScene(), 1e-3); 100 assertEquals(190, camera.getFarClipInScene(), 1e-3); 101 } 102 103 /** 104 * Test of getFarClipInScene method, of class Camera. 105 */ 106 @Test 107 public void testGetFarClipInScene() { 108 Camera camera = new PerspectiveCamera(); 109 camera.setTranslateZ(-10); 110 camera.setFarClip(60); 111 112 assertEquals(50, camera.getFarClipInScene(), 1e-3); 113 } 114 115 @Test 116 public void testLocalToSceneTxChange() { 117 Camera camera = new PerspectiveCamera(); 118 camera.setTranslateZ(-10); 119 assertEquals(0.1, camera.getNearClip(), 1e-3); 120 assertEquals(100, camera.getFarClip(), 1e-3); 121 assertEquals(-9.9, camera.getNearClipInScene(), 1e-3); 122 assertEquals(90, camera.getFarClipInScene(), 1e-3); 123 124 camera.setTranslateZ(100); 125 assertEquals(0.1, camera.getNearClip(), 1e-3); 126 assertEquals(100, camera.getFarClip(), 1e-3); 127 assertEquals(100.1, camera.getNearClipInScene(), 1e-3); 128 assertEquals(200, camera.getFarClipInScene(), 1e-3); 129 } 130 131 /** 132 * Test of getSceneToLocalTransform method, of class Camera. 133 */ 134 @Test 135 public void testGetSceneToLocalTransform() { 136 Camera camera = new PerspectiveCamera(); 137 new Scene(new Group(camera)); 138 camera.setTranslateX(300); 139 camera.getParent().setTranslateY(100); 140 Affine3D expected = new Affine3D(); 141 try { 142 camera.getLocalToSceneTransform().createInverse().impl_apply(expected); 143 } catch (NonInvertibleTransformException ex) { 144 fail("NonInvertibleTransformException when compute sceneToLocalTx."); 145 } 146 assertEquals(expected, camera.getSceneToLocalTransform()); 147 148 camera.setTranslateZ(-10); 149 camera.setScaleX(10); 150 expected.setToIdentity(); 151 try { 152 camera.getLocalToSceneTransform().createInverse().impl_apply(expected); 153 } catch (NonInvertibleTransformException ex) { 154 fail("NonInvertibleTransformException when compute sceneToLocalTx."); 155 } 156 assertEquals(expected, camera.getSceneToLocalTransform()); 157 } 158 159 /** 160 * Test of getSceneToLocalTransform method when camera is not in scene. 161 */ 162 @Test 163 public void testGetSceneToLocalTransformWhenNotInScene() { 164 Camera camera = new PerspectiveCamera(); 165 Affine3D expected = new Affine3D(); 166 assertEquals(expected, camera.getSceneToLocalTransform()); 167 168 try { 169 camera.getLocalToSceneTransform().createInverse().impl_apply(expected); 170 } catch (NonInvertibleTransformException ex) { 171 fail("NonInvertibleTransformException when compute sceneToLocalTx."); 172 } 173 assertEquals(expected, camera.getSceneToLocalTransform()); 174 175 camera.setTranslateZ(-10); 176 camera.setScaleX(10); 177 expected.setToIdentity(); 178 try { 179 camera.getLocalToSceneTransform().createInverse().impl_apply(expected); 180 } catch (NonInvertibleTransformException ex) { 181 fail("NonInvertibleTransformException when compute sceneToLocalTx."); 182 } 183 assertEquals(expected, camera.getSceneToLocalTransform()); 184 } 185 186 @Test 187 public void testViewSize() { 188 final Scene scene = new Scene(new Group(), 300, 200); 189 Camera camera = new PerspectiveCamera(); 190 scene.setCamera(camera); 191 assertEquals(300.0, camera.getViewWidth(), 1.0e-20); 192 assertEquals(200.0, camera.getViewHeight(), 1.0e-20); 193 } 194 195 @Test 196 public void testDefaultCamera() { 197 final Scene scene = new Scene(new Group(), 300, 200); 198 Camera camera = scene.getEffectiveCamera(); 199 200 assertTrue(camera instanceof ParallelCamera); 201 assertEquals(300.0, camera.getViewWidth(), 1.0e-20); 202 assertEquals(200.0, camera.getViewHeight(), 1.0e-20); 203 } 204 205 @Test 206 public void testParallelProjViewTx() { 207 final Scene scene = new Scene(new Group(), 300, 200); 208 Camera camera = new ParallelCamera(); 209 scene.setCamera(camera); 210 211 GeneralTransform3D expected = new GeneralTransform3D(); 212 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 213 214 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 215 } 216 217 @Test 218 public void testParallelProjViewTxWithMovedCamera() { 219 final Scene scene = new Scene(new Group(), 300, 200); 220 Camera camera = new ParallelCamera(); 221 scene.setCamera(camera); 222 scene.getRoot().getChildren().add(camera); 223 scene.getRoot().setTranslateX(50); 224 camera.setTranslateY(60); 225 226 GeneralTransform3D expected = new GeneralTransform3D(); 227 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 228 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 229 230 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 231 } 232 233 @Test 234 public void testParallelProjViewTxWithMovedCameraNotInScene() { 235 final Scene scene = new Scene(new Group(), 300, 200); 236 Camera camera = new ParallelCamera(); 237 scene.setCamera(camera); 238 scene.getRoot().setTranslateX(50); 239 camera.setTranslateX(50); 240 camera.setTranslateY(60); 241 242 GeneralTransform3D expected = new GeneralTransform3D(); 243 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 244 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 245 246 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 247 } 248 249 @Test 250 public void testParallelProjViewTxWithMovedCameraNotInScene2() { 251 final Scene scene = new Scene(new Group(), 300, 200); 252 Camera camera = new ParallelCamera(); 253 scene.setCamera(camera); 254 scene.getRoot().setTranslateX(50); 255 new Group(camera); 256 camera.getParent().setTranslateX(50); 257 camera.setTranslateY(60); 258 259 GeneralTransform3D expected = new GeneralTransform3D(); 260 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 261 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 262 263 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 264 } 265 266 @Test 267 public void testPerspectiveProjViewTx() { 268 final Scene scene = new Scene(new Group(), 300, 200); 269 PerspectiveCamera camera = new PerspectiveCamera(); 270 scene.setCamera(camera); 271 272 TransformHelper.assertMatrix(camera.getProjViewTransform(), DEFAULT_PROJVIEW_TX); 273 } 274 275 @Test 276 public void testPerspectiveProjViewTxWithModifiedParams() { 277 final Scene scene = new Scene(new Group(), 300, 200); 278 PerspectiveCamera camera = new PerspectiveCamera(); 279 camera.setVerticalFieldOfView(false); 280 camera.setFieldOfView(40); 281 camera.setNearClip(1); 282 camera.setFarClip(200); 283 scene.setCamera(camera); 284 285 GeneralTransform3D expected = new GeneralTransform3D(); 286 expected.perspective(false, Math.toRadians(40), 1.5, 1.0, 200); 287 288 final double tanOfHalfFOV = Math.tan(Math.toRadians(40) / 2.0); 289 290 Affine3D view = new Affine3D(); 291 final double scale = 2.0 * tanOfHalfFOV / 300; 292 293 view.setToTranslation(-tanOfHalfFOV, tanOfHalfFOV / 1.5, 0.0); 294 view.translate(0, 0, -1); 295 view.rotate(Math.PI, 1, 0, 0); 296 view.scale(scale, scale, scale); 297 298 expected.mul(view); 299 300 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 301 } 302 303 @Test 304 public void testPerspectiveProjViewTxWithMovedCamera() { 305 final Scene scene = new Scene(new Group(), 300, 200); 306 PerspectiveCamera camera = new PerspectiveCamera(); 307 scene.setCamera(camera); 308 scene.getRoot().getChildren().add(camera); 309 scene.getRoot().setTranslateX(50); 310 camera.setTranslateY(60); 311 312 GeneralTransform3D expected = new GeneralTransform3D(); 313 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 314 315 final double tanOfHalfFOV = Math.tan(Math.toRadians(30) / 2.0); 316 317 Affine3D view = new Affine3D(); 318 final double scale = 2.0 * tanOfHalfFOV / 200; 319 320 view.setToTranslation(-tanOfHalfFOV * 1.5, tanOfHalfFOV, 0.0); 321 view.translate(0, 0, -1); 322 view.rotate(Math.PI, 1, 0, 0); 323 view.scale(scale, scale, scale); 324 325 expected.mul(view); 326 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 327 328 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 329 } 330 331 @Test 332 public void testPerspectiveProjViewTxWithMovedCameraNotInScene() { 333 final Scene scene = new Scene(new Group(), 300, 200); 334 PerspectiveCamera camera = new PerspectiveCamera(); 335 scene.setCamera(camera); 336 scene.getRoot().setTranslateX(50); 337 camera.setTranslateX(50); 338 camera.setTranslateY(60); 339 340 GeneralTransform3D expected = new GeneralTransform3D(); 341 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 342 343 final double tanOfHalfFOV = Math.tan(Math.toRadians(30) / 2.0); 344 345 Affine3D view = new Affine3D(); 346 final double scale = 2.0 * tanOfHalfFOV / 200; 347 348 view.setToTranslation(-tanOfHalfFOV * 1.5, tanOfHalfFOV, 0.0); 349 view.translate(0, 0, -1); 350 view.rotate(Math.PI, 1, 0, 0); 351 view.scale(scale, scale, scale); 352 353 expected.mul(view); 354 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 355 356 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 357 } 358 359 @Test 360 public void testPerspectiveProjViewTxWithMovedCameraNotInScene2() { 361 final Scene scene = new Scene(new Group(), 300, 200); 362 PerspectiveCamera camera = new PerspectiveCamera(); 363 scene.setCamera(camera); 364 scene.getRoot().setTranslateX(50); 365 new Group(camera); 366 camera.getParent().setTranslateX(50); 367 camera.setTranslateY(60); 368 369 GeneralTransform3D expected = new GeneralTransform3D(); 370 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 371 372 final double tanOfHalfFOV = Math.tan(Math.toRadians(30) / 2.0); 373 374 Affine3D view = new Affine3D(); 375 final double scale = 2.0 * tanOfHalfFOV / 200; 376 377 view.setToTranslation(-tanOfHalfFOV * 1.5, tanOfHalfFOV, 0.0); 378 view.translate(0, 0, -1); 379 view.rotate(Math.PI, 1, 0, 0); 380 view.scale(scale, scale, scale); 381 382 expected.mul(view); 383 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 384 385 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 386 } 387 388 @Test 389 public void testPerspectiveProjViewTxWithFixedEye() { 390 final Scene scene = new Scene(new Group(), 300, 200); 391 PerspectiveCamera camera = new PerspectiveCamera(true); 392 scene.setCamera(camera); 393 394 GeneralTransform3D expected = new GeneralTransform3D(); 395 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 396 397 Affine3D view = new Affine3D(); 398 view.rotate(Math.PI, 1, 0, 0); 399 400 expected.mul(view); 401 402 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 403 } 404 405 @Test 406 public void testPerspectiveProjViewTxWithFixedEyeAndModifiedParams() { 407 final Scene scene = new Scene(new Group(), 300, 200); 408 PerspectiveCamera camera = new PerspectiveCamera(true); 409 camera.setVerticalFieldOfView(false); 410 camera.setFieldOfView(40); 411 camera.setNearClip(1); 412 camera.setFarClip(200); 413 scene.setCamera(camera); 414 415 GeneralTransform3D expected = new GeneralTransform3D(); 416 expected.perspective(false, Math.toRadians(40), 1.5, 1.0, 200); 417 418 Affine3D view = new Affine3D(); 419 view.rotate(Math.PI, 1, 0, 0); 420 421 expected.mul(view); 422 423 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 424 } 425 426 @Test 427 public void testPerspectiveProjViewTxWithFixedEyeAndMovedCamera() { 428 final Scene scene = new Scene(new Group(), 300, 200); 429 PerspectiveCamera camera = new PerspectiveCamera(true); 430 scene.setCamera(camera); 431 scene.getRoot().getChildren().add(camera); 432 scene.getRoot().setTranslateX(50); 433 camera.setTranslateY(60); 434 435 GeneralTransform3D expected = new GeneralTransform3D(); 436 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 437 438 Affine3D view = new Affine3D(); 439 view.rotate(Math.PI, 1, 0, 0); 440 441 expected.mul(view); 442 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 443 444 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 445 } 446 447 @Test 448 public void testPerspectiveProjViewTxWithFixedEyeAndMovedCameraNotInScene() { 449 final Scene scene = new Scene(new Group(), 300, 200); 450 PerspectiveCamera camera = new PerspectiveCamera(true); 451 scene.setCamera(camera); 452 scene.getRoot().setTranslateX(50); 453 camera.setTranslateX(50); 454 camera.setTranslateY(60); 455 456 GeneralTransform3D expected = new GeneralTransform3D(); 457 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 458 459 Affine3D view = new Affine3D(); 460 view.rotate(Math.PI, 1, 0, 0); 461 462 expected.mul(view); 463 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 464 465 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 466 } 467 468 @Test 469 public void testPerspectiveProjViewTxWithFixedEyeAndMovedCameraNotInScene2() { 470 final Scene scene = new Scene(new Group(), 300, 200); 471 PerspectiveCamera camera = new PerspectiveCamera(true); 472 scene.setCamera(camera); 473 scene.getRoot().setTranslateX(50); 474 new Group(camera); 475 camera.getParent().setTranslateX(50); 476 camera.setTranslateY(60); 477 478 GeneralTransform3D expected = new GeneralTransform3D(); 479 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 100); 480 481 Affine3D view = new Affine3D(); 482 view.rotate(Math.PI, 1, 0, 0); 483 484 expected.mul(view); 485 expected.mul(Affine3D.getTranslateInstance(-50, -60)); 486 487 TransformHelper.assertMatrix(camera.getProjViewTransform(), expected); 488 } 489 490 @Test 491 public void testParallelCameraPosition() { 492 Scene scene = new Scene(new Group(), 300, 200); 493 Camera cam = new ParallelCamera(); 494 scene.setCamera(cam); 495 Vec3d v = cam.computePosition(null); 496 assertEquals(150.0, v.x, 0.000001); 497 assertEquals(100.0, v.y, 0.000001); 498 assertEquals(-373.205080, v.z, 0.000001); 499 } 500 501 @Test 502 public void testPerspectiveCameraPositionWithFixedEye() { 503 Scene scene = new Scene(new Group(), 300, 200); 504 Camera cam = new PerspectiveCamera(true); 505 scene.setCamera(cam); 506 Vec3d v = cam.computePosition(null); 507 assertEquals(0.0, v.x, 0.000001); 508 assertEquals(0.0, v.y, 0.000001); 509 assertEquals(0.0, v.z, 0.000001); 510 } 511 512 @Test 513 public void testPerspectiveCameraPosition() { 514 Scene scene = new Scene(new Group(), 300, 200); 515 Camera cam = new PerspectiveCamera(); 516 scene.setCamera(cam); 517 Vec3d v = cam.computePosition(null); 518 assertEquals(150.0, v.x, 0.000001); 519 assertEquals(100.0, v.y, 0.000001); 520 assertEquals(-373.205080, v.z, 0.000001); 521 } 522 523 @Test 524 public void perspectiveCameraShouldSyncWhenAssignedToScene() { 525 final Scene scene = new Scene(new Group(), 300, 200); 526 PerspectiveCamera camera = new StubPerspectiveCamera(); 527 scene.setCamera(camera); 528 Stage stage = new Stage(); 529 stage.setScene(scene); 530 stage.show(); 531 532 Toolkit.getToolkit().firePulse(); 533 534 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 535 536 assertEquals(300, pc.getViewWidth(), 0.00001); 537 assertEquals(200, pc.getViewHeight(), 0.00001); 538 539 TransformHelper.assertMatrix(pc.getProjViewTx(), DEFAULT_PROJVIEW_TX); 540 assertTrue(pc.isVerticalFieldOfView()); 541 assertEquals(30, pc.getFieldOfView(), 0.00001); 542 assertEquals(150.0, pc.getPosition().x, 0.000001); 543 assertEquals(100.0, pc.getPosition().y, 0.000001); 544 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 545 } 546 547 @Test 548 public void perspectiveCameraShouldSyncWhenAssignedToSubScene() { 549 SubScene sub = new SubScene(new Group(), 300, 200); 550 final Scene scene = new Scene(new Group(sub), 600, 300); 551 PerspectiveCamera camera = new StubPerspectiveCamera(); 552 sub.setCamera(camera); 553 Stage stage = new Stage(); 554 stage.setScene(scene); 555 stage.show(); 556 557 Toolkit.getToolkit().firePulse(); 558 559 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 560 561 assertEquals(300, pc.getViewWidth(), 0.00001); 562 assertEquals(200, pc.getViewHeight(), 0.00001); 563 564 TransformHelper.assertMatrix(pc.getProjViewTx(), DEFAULT_PROJVIEW_TX); 565 assertTrue(pc.isVerticalFieldOfView()); 566 assertEquals(30, pc.getFieldOfView(), 0.00001); 567 assertEquals(150.0, pc.getPosition().x, 0.000001); 568 assertEquals(100.0, pc.getPosition().y, 0.000001); 569 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 570 } 571 572 @Test 573 public void parallelCameraShouldSyncWhenAssignedToScene() { 574 final Scene scene = new Scene(new Group(), 300, 200); 575 ParallelCamera camera = new StubParallelCamera(); 576 scene.setCamera(camera); 577 Stage stage = new Stage(); 578 stage.setScene(scene); 579 stage.show(); 580 581 Toolkit.getToolkit().firePulse(); 582 583 StubNGParallelCamera pc = camera.impl_getPeer(); 584 585 assertEquals(300, pc.getViewWidth(), 0.00001); 586 assertEquals(200, pc.getViewHeight(), 0.00001); 587 588 GeneralTransform3D expected = new GeneralTransform3D(); 589 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 590 591 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 592 assertEquals(150.0, pc.getPosition().x, 0.000001); 593 assertEquals(100.0, pc.getPosition().y, 0.000001); 594 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 595 } 596 597 @Test 598 public void parallelCameraShouldSyncWhenAssignedToSubScene() { 599 SubScene sub = new SubScene(new Group(), 300, 200); 600 final Scene scene = new Scene(new Group(sub), 600, 300); 601 ParallelCamera camera = new StubParallelCamera(); 602 sub.setCamera(camera); 603 Stage stage = new Stage(); 604 stage.setScene(scene); 605 stage.show(); 606 607 Toolkit.getToolkit().firePulse(); 608 609 StubNGParallelCamera pc = camera.impl_getPeer(); 610 611 assertEquals(300, pc.getViewWidth(), 0.00001); 612 assertEquals(200, pc.getViewHeight(), 0.00001); 613 614 GeneralTransform3D expected = new GeneralTransform3D(); 615 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 616 617 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 618 assertEquals(150.0, pc.getPosition().x, 0.000001); 619 assertEquals(100.0, pc.getPosition().y, 0.000001); 620 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 621 } 622 623 @Test 624 public void sceneDefaultCameraShouldSyncInTheBeginning() { 625 final Scene scene = new Scene(new Group(), 300, 200); 626 ParallelCamera camera = new StubParallelCamera(); 627 scene.setCamera(camera); 628 Stage stage = new Stage(); 629 stage.setScene(scene); 630 stage.show(); 631 632 Toolkit.getToolkit().firePulse(); 633 634 StubNGParallelCamera pc = scene.getEffectiveCamera().impl_getPeer(); 635 636 assertEquals(300, pc.getViewWidth(), 0.00001); 637 assertEquals(200, pc.getViewHeight(), 0.00001); 638 639 GeneralTransform3D expected = new GeneralTransform3D(); 640 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 641 642 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 643 assertEquals(150.0, pc.getPosition().x, 0.000001); 644 assertEquals(100.0, pc.getPosition().y, 0.000001); 645 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 646 } 647 648 @Test 649 public void subSceneDefaultCameraShouldSyncInTheBeginning() { 650 SubScene sub = new SubScene(new Group(), 300, 200); 651 final Scene scene = new Scene(new Group(sub), 600, 300); 652 ParallelCamera camera = new StubParallelCamera(); 653 sub.setCamera(camera); 654 Stage stage = new Stage(); 655 stage.setScene(scene); 656 stage.show(); 657 658 Toolkit.getToolkit().firePulse(); 659 660 StubNGParallelCamera pc = sub.getEffectiveCamera().impl_getPeer(); 661 662 assertEquals(300, pc.getViewWidth(), 0.00001); 663 assertEquals(200, pc.getViewHeight(), 0.00001); 664 665 GeneralTransform3D expected = new GeneralTransform3D(); 666 expected.ortho(0.0, 300, 200, 0.0, -150, 150); 667 668 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 669 assertEquals(150.0, pc.getPosition().x, 0.000001); 670 assertEquals(100.0, pc.getPosition().y, 0.000001); 671 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 672 } 673 674 @Test 675 public void resizeShouldTriggerSync() { 676 SubScene sub = new SubScene(new Group(), 400, 300); 677 final Scene scene = new Scene(new Group(sub), 600, 300); 678 PerspectiveCamera camera = new StubPerspectiveCamera(); 679 sub.setCamera(camera); 680 Stage stage = new Stage(); 681 stage.setScene(scene); 682 stage.show(); 683 Toolkit.getToolkit().firePulse(); 684 685 sub.setWidth(300); 686 sub.setHeight(200); 687 Toolkit.getToolkit().firePulse(); 688 689 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 690 691 assertEquals(300, pc.getViewWidth(), 0.00001); 692 assertEquals(200, pc.getViewHeight(), 0.00001); 693 694 TransformHelper.assertMatrix(pc.getProjViewTx(), DEFAULT_PROJVIEW_TX); 695 assertEquals(150.0, pc.getPosition().x, 0.000001); 696 assertEquals(100.0, pc.getPosition().y, 0.000001); 697 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 698 } 699 700 @Test 701 public void clipChangeShouldTriggerSync() { 702 final Scene scene = new Scene(new Group(), 300, 200); 703 PerspectiveCamera camera = new StubPerspectiveCamera(); 704 scene.setCamera(camera); 705 Stage stage = new Stage(); 706 stage.setScene(scene); 707 stage.show(); 708 Toolkit.getToolkit().firePulse(); 709 710 camera.setFarClip(250.0); 711 Toolkit.getToolkit().firePulse(); 712 713 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 714 715 GeneralTransform3D expected = new GeneralTransform3D(); 716 expected.perspective(true, Math.toRadians(30), 1.5, 0.1, 250); 717 final double tanOfHalfFOV = Math.tan(Math.toRadians(30) / 2.0); 718 Affine3D view = new Affine3D(); 719 final double scale = 2.0 * tanOfHalfFOV / 200; 720 view.setToTranslation(-tanOfHalfFOV * 1.5, tanOfHalfFOV, 0.0); 721 view.translate(0, 0, -1); 722 view.rotate(Math.PI, 1, 0, 0); 723 view.scale(scale, scale, scale); 724 expected.mul(view); 725 726 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 727 } 728 729 @Test 730 public void fieldOfViewChangeShouldTriggerSync() { 731 final Scene scene = new Scene(new Group(), 300, 200); 732 PerspectiveCamera camera = new StubPerspectiveCamera(); 733 scene.setCamera(camera); 734 Stage stage = new Stage(); 735 stage.setScene(scene); 736 stage.show(); 737 Toolkit.getToolkit().firePulse(); 738 739 camera.setFieldOfView(45.0); 740 Toolkit.getToolkit().firePulse(); 741 742 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 743 744 GeneralTransform3D expected = new GeneralTransform3D(); 745 expected.perspective(true, Math.toRadians(45), 1.5, 0.1, 100); 746 final double tanOfHalfFOV = Math.tan(Math.toRadians(45) / 2.0); 747 Affine3D view = new Affine3D(); 748 final double scale = 2.0 * tanOfHalfFOV / 200; 749 view.setToTranslation(-tanOfHalfFOV * 1.5, tanOfHalfFOV, 0.0); 750 view.translate(0, 0, -1); 751 view.rotate(Math.PI, 1, 0, 0); 752 view.scale(scale, scale, scale); 753 expected.mul(view); 754 755 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 756 assertEquals(150.0, pc.getPosition().x, 0.000001); 757 assertEquals(100.0, pc.getPosition().y, 0.000001); 758 assertEquals(-241.421356, pc.getPosition().z, 0.000001); 759 } 760 761 @Test 762 public void verticalFOVChangeShouldTriggerSync() { 763 final Scene scene = new Scene(new Group(), 300, 200); 764 PerspectiveCamera camera = new StubPerspectiveCamera(); 765 scene.setCamera(camera); 766 Stage stage = new Stage(); 767 stage.setScene(scene); 768 stage.show(); 769 Toolkit.getToolkit().firePulse(); 770 771 camera.setVerticalFieldOfView(false); 772 Toolkit.getToolkit().firePulse(); 773 774 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 775 776 GeneralTransform3D expected = new GeneralTransform3D(); 777 expected.perspective(false, Math.toRadians(30), 1.5, 0.1, 100); 778 final double tanOfHalfFOV = Math.tan(Math.toRadians(30) / 2.0); 779 Affine3D view = new Affine3D(); 780 final double scale = 2.0 * tanOfHalfFOV / 300; 781 view.setToTranslation(-tanOfHalfFOV, tanOfHalfFOV / 1.5, 0.0); 782 view.translate(0, 0, -1); 783 view.rotate(Math.PI, 1, 0, 0); 784 view.scale(scale, scale, scale); 785 expected.mul(view); 786 787 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 788 assertEquals(150.0, pc.getPosition().x, 0.000001); 789 assertEquals(100.0, pc.getPosition().y, 0.000001); 790 assertEquals(-559.80762, pc.getPosition().z, 0.00001); 791 } 792 793 @Test 794 public void localToSceneChangeShouldTriggerSync() { 795 PerspectiveCamera camera = new StubPerspectiveCamera(); 796 final Scene scene = new Scene(new Group(new Group(camera)), 300, 200); 797 scene.setCamera(camera); 798 Stage stage = new Stage(); 799 stage.setScene(scene); 800 stage.show(); 801 Toolkit.getToolkit().firePulse(); 802 803 camera.getParent().setTranslateX(200); 804 Toolkit.getToolkit().firePulse(); 805 806 StubNGPerspectiveCamera pc = camera.impl_getPeer(); 807 808 GeneralTransform3D expected = new GeneralTransform3D(); 809 expected.set(DEFAULT_PROJVIEW_TX); 810 expected.mul(Affine3D.getTranslateInstance(-200, 0)); 811 812 TransformHelper.assertMatrix(pc.getProjViewTx(), expected); 813 assertEquals(350.0, pc.getPosition().x, 0.000001); 814 assertEquals(100.0, pc.getPosition().y, 0.000001); 815 assertEquals(-373.205080, pc.getPosition().z, 0.000001); 816 TransformHelper.assertMatrix(pc.getWorldTransform(), Affine3D.getTranslateInstance(200, 0)); 817 } 818 819 private class StubPerspectiveCamera extends PerspectiveCamera { 820 @Override 821 protected NGNode impl_createPeer() { 822 return new StubNGPerspectiveCamera(isFixedEyeAtCameraZero()); 823 } 824 } 825 826 private class StubNGPerspectiveCamera extends NGPerspectiveCamera { 827 double viewWidth, viewHeight; 828 Vec3d position; 829 GeneralTransform3D projViewTx; 830 Affine3D localToWorldTx; 831 float fieldOfView; 832 boolean verticalFieldOfView; 833 834 public StubNGPerspectiveCamera(boolean fixedEyeAtCameraZero) { 835 super(fixedEyeAtCameraZero); 836 } 837 838 @Override public void setViewWidth(double viewWidth) { this.viewWidth = viewWidth; } 839 public double getViewWidth() { return viewWidth; } 840 841 @Override public void setViewHeight(double viewHeight) { this.viewHeight = viewHeight; } 842 public double getViewHeight() { return viewHeight; } 843 844 @Override public void setPosition(Vec3d position) { this.position = position; } 845 public Vec3d getPosition() { return position; } 846 847 @Override public void setWorldTransform(Affine3D localToWorldTx) { this.localToWorldTx = localToWorldTx; } 848 public Affine3D getWorldTransform() { return localToWorldTx; } 849 850 @Override public void setProjViewTransform(GeneralTransform3D projViewTx) { this.projViewTx = projViewTx; } 851 public GeneralTransform3D getProjViewTx() { return projViewTx; } 852 853 @Override public void setFieldOfView(float fieldOfView) { this.fieldOfView = fieldOfView; } 854 public double getFieldOfView() { return fieldOfView; } 855 856 @Override public void setVerticalFieldOfView(boolean verticalFieldOfView) { this.verticalFieldOfView = verticalFieldOfView; } 857 public boolean isVerticalFieldOfView() { return this.verticalFieldOfView; } 858 } 859 860 private class StubParallelCamera extends ParallelCamera { 861 @Override 862 protected NGNode impl_createPeer() { 863 return new StubNGParallelCamera(); 864 } 865 } 866 867 private class StubNGParallelCamera extends NGParallelCamera { 868 double viewWidth, viewHeight; 869 Vec3d position; 870 GeneralTransform3D projViewTx; 871 Affine3D localToWorldTx; 872 873 @Override public void setViewWidth(double viewWidth) { this.viewWidth = viewWidth; } 874 public double getViewWidth() { return viewWidth; } 875 876 @Override public void setViewHeight(double viewHeight) { this.viewHeight = viewHeight; } 877 public double getViewHeight() { return viewHeight; } 878 879 @Override public void setPosition(Vec3d position) { this.position = position; } 880 public Vec3d getPosition() { return position; } 881 882 @Override public void setWorldTransform(Affine3D localToWorldTx) { this.localToWorldTx = localToWorldTx; } 883 public Affine3D getWorldTransform() { return localToWorldTx; } 884 885 @Override public void setProjViewTransform(GeneralTransform3D projViewTx) { this.projViewTx = projViewTx; } 886 public GeneralTransform3D getProjViewTx() { return projViewTx; } 887 } 888 }