From 1efec06bdcc8f332da2ab22e048e9a675cf7839f Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Fri, 8 Sep 2017 14:21:03 +1200 Subject: [PATCH] View3D can untrack objects and zoom in different modes - updateDistance zooms between 0 and infinity - Camera switches from third person to bird's eye when reaching a set distance - Only one subject can be tracked at a time #story[1190] --- .../Controllers/RaceController.java | 4 ++ .../main/java/visualiser/layout/View3D.java | 64 ++++++++++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index 0bbc2ad6..4a8addb7 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -225,6 +225,10 @@ public class RaceController extends Controller { trackBoat.start(); } view3D.updatePivot(new Translate(250, 0, 210)); + + view3D.setOnScroll(e -> { + view3D.updateDistance(e.getDeltaY()); + }); } diff --git a/racevisionGame/src/main/java/visualiser/layout/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java index a6afb439..3f867791 100644 --- a/racevisionGame/src/main/java/visualiser/layout/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -1,5 +1,7 @@ package visualiser.layout; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.geometry.Point3D; @@ -31,6 +33,10 @@ public class View3D extends Pane { * Map for selecting Subject3D from Shape3D */ private Map selectionMap; + /** + * Subject tracked by camera + */ + private Subject3D target; /** * Rendering container for shapes */ @@ -60,12 +66,23 @@ public class View3D extends Pane { */ private Rotate pitch; + private ChangeListener pivotHeading = (o, prev, curr) -> yaw.setAngle((double)curr); + + private ChangeListener pivotX = (o, prev, curr) -> pivot.setX((double)curr); + + private ChangeListener pivotY = (o, prev, curr) -> pivot.setY((double)curr); + + private ChangeListener pivotZ = (o, prev, curr) -> pivot.setZ((double)curr); + + private double THIRD_PERSON_LIMIT = 100; + /** * Default constructor for View3D. Sets up Scene and PerspectiveCamera. */ public View3D() { world = new Group(); selectionMap = new HashMap<>(); + target = null; SubScene scene = new SubScene(world, 300, 300); scene.widthProperty().bind(this.widthProperty()); @@ -77,14 +94,7 @@ public class View3D extends Pane { scene.setOnMousePressed(e -> { PickResult result = e.getPickResult(); if(result != null && result.getIntersectedNode() != null && result.getIntersectedNode() instanceof Shape3D) { - Subject3D target = selectionMap.get(result.getIntersectedNode()); - target.getPosition().xProperty().addListener((o, prev, curr) -> pivot.setX((double)curr)); - target.getPosition().yProperty().addListener((o, prev, curr) -> pivot.setY((double)curr)); - target.getPosition().zProperty().addListener((o, prev, curr) -> pivot.setZ((double)curr)); - target.getHeading().angleProperty().addListener((o, prev, curr) -> setYaw((double)curr)); - - this.setDistance(100); - this.setPitch(30); + trackSubject(selectionMap.get(result.getIntersectedNode())); } }); @@ -132,6 +142,31 @@ public class View3D extends Pane { }); } + private void untrackSubject() { + if(target != null) { + target.getPosition().xProperty().removeListener(pivotX); + target.getPosition().yProperty().removeListener(pivotY); + target.getPosition().zProperty().removeListener(pivotZ); + target.getHeading().angleProperty().removeListener(pivotHeading); + } + } + + private void trackSubject(Subject3D subject) { + untrackSubject(); + target = subject; + + updatePivot(target.getPosition()); + setYaw(target.getHeading().getAngle()); + + target.getPosition().xProperty().addListener(pivotX); + target.getPosition().yProperty().addListener(pivotY); + target.getPosition().zProperty().addListener(pivotZ); + target.getHeading().angleProperty().addListener(pivotHeading); + + this.setDistance(THIRD_PERSON_LIMIT); + this.setPitch(20); + } + public void setNearClip(double nearClip) { this.nearClip = nearClip; } @@ -155,7 +190,18 @@ public class View3D extends Pane { } public void updateDistance(double delta) { - this.distance.setZ(this.distance.getZ() - delta); + double distance = -this.distance.getZ() + delta; + + if(distance <= 0) { + this.setDistance(0); + } else if(distance > THIRD_PERSON_LIMIT) { + untrackSubject(); + this.setYaw(0); + this.setPitch(60); + this.setDistance(distance); + } else { + this.setDistance(distance); + } } /**