From 91c442e46554f7bb3c7e03bda32e08a03eb3b4c0 Mon Sep 17 00:00:00 2001 From: Joseph Date: Thu, 21 Sep 2017 22:25:39 +1200 Subject: [PATCH 01/16] Set up architecture for next mark arrow and did a 2d template when the camera is zoomed out. #story[1299] --- .../Controllers/NextMarkController.java | 67 +++++++++++++++++ .../Controllers/RaceViewController.java | 74 +++++++++---------- .../visualiser/scenes/newRaceView.fxml | 9 ++- .../resources/visualiser/scenes/nextMark.fxml | 45 +++++++++++ 4 files changed, 155 insertions(+), 40 deletions(-) create mode 100644 racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java create mode 100644 racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml diff --git a/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java b/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java new file mode 100644 index 00000000..001a1a60 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java @@ -0,0 +1,67 @@ +package visualiser.Controllers; + +import com.interactivemesh.jfx.importer.stl.StlMeshImporter; +import javafx.animation.AnimationTimer; +import javafx.fxml.FXML; +import javafx.scene.layout.Pane; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; +import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.Cylinder; +import javafx.scene.shape.MeshView; +import shared.model.Bearing; +import shared.model.CompoundMark; +import shared.model.GPSCoordinate; +import visualiser.model.VisualiserBoat; + +import java.net.URL; +import java.util.Observable; +import java.util.Observer; + +public class NextMarkController { + private @FXML StackPane arrowStackPane2d; + private @FXML Pane pane2d; + private @FXML Pane pane3d; + + private VisualiserBoat boat; + + public void initialiseArrowView(VisualiserBoat boat) { + this.boat = boat; + pane2d.setVisible(true); + pane3d.setVisible(false); + initialise2dArrowView(); + initialise3dArrowView(); + } + + private void initialise2dArrowView() { + AnimationTimer arrow2d = new AnimationTimer() { + @Override + public void handle(long now) { + CompoundMark target = boat.getCurrentLeg().getEndCompoundMark(); + Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate()); + arrowStackPane2d.setRotate(headingToMark.degrees()); + } + }; + arrow2d.start(); + } + + private void initialise3dArrowView() { + URL asset = this.getClass().getClassLoader().getResource("assets/arrow V1.0.4.stl"); + StlMeshImporter importer = new StlMeshImporter(); + importer.read(asset); + + MeshView arrow = new MeshView(importer.getImport()); + PhongMaterial arrowMat = new PhongMaterial(Color.RED); + arrow.setMaterial(arrowMat); + } + + public void show2d() { + pane3d.setVisible(false); + pane2d.setVisible(true); + } + + public void show3d() { + pane2d.setVisible(false); + pane3d.setVisible(true); + } +} diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java index c2153c1f..80ca9fa7 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java @@ -16,10 +16,12 @@ import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.Material; import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.Cylinder; import javafx.scene.shape.MeshView; import javafx.scene.shape.Shape3D; import javafx.scene.transform.Translate; @@ -77,9 +79,11 @@ public class RaceViewController extends Controller { // note: it says it's not used but it is! do not remove :) private @FXML ArrowController arrowController; + private @FXML NextMarkController nextMarkController; private @FXML GridPane canvasBase; private @FXML SplitPane racePane; private @FXML StackPane arrowPane; + private @FXML Pane nextMarkPane; private @FXML Label timer; private @FXML Label FPS; private @FXML Label timeZone; @@ -204,25 +208,13 @@ public class RaceViewController extends Controller { * Initialises the various UI components to listen to the {@link #visualiserRace}. */ private void initialiseRaceVisuals() { - - // Import arrow mesh - URL asset = this.getClass().getClassLoader().getResource("assets/arrow V1.0.4.stl"); - StlMeshImporter importer = new StlMeshImporter(); - importer.read(asset); - - MeshView arrow = new MeshView(importer.getImport()); - PhongMaterial arrowMat = new PhongMaterial(Color.RED); - arrow.setMaterial(arrowMat); - - this.nextMarkArrow = new Annotation3D(arrow); - this.nextMarkArrow.setScale(0.1); - // initialise displays initialiseFps(); initialiseInfoTable(); initialiseView3D(this.visualiserRace); initialiseRaceClock(); raceTimer(); // start the timer + nextMarkPane.toFront(); new Sparkline(this.raceState, this.sparklineChart); timeZone.setText(this.raceState.getRaceClock().getTimeZone()); arrowController.setWindProperty(this.raceState.windProperty()); @@ -231,6 +223,13 @@ public class RaceViewController extends Controller { private void initialiseView3D(VisualiserRaceEvent race) { viewSubjects = FXCollections.observableArrayList(); + try { + nextMarkController.initialiseArrowView(race.getVisualiserRaceState().getBoat(race.getVisualiserRaceState().getPlayerBoatID())); + System.out.println("hi"); + } catch (BoatNotFoundException e) { + e.printStackTrace(); + } + AmbientLight ambientLight = new AmbientLight(Color.web("#CCCCFF")); ambientLight.setTranslateX(250); ambientLight.setTranslateZ(210); @@ -417,35 +416,32 @@ public class RaceViewController extends Controller { } private void addThirdPersonAnnotations(Subject3D subject3D) { - viewSubjects.add(nextMarkArrow); - final VisualiserBoat boat; - try { - boat = visualiserRace.getVisualiserRaceState().getBoat(subject3D.getSourceID()); - } catch (BoatNotFoundException e) { - e.printStackTrace(); - return; - } - arrowToNextMark = new AnimationTimer() { - @Override - public void handle(long now) { - CompoundMark target = boat.getCurrentLeg().getEndCompoundMark(); - Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate()); - - nextMarkArrow.setX(view3D.getPivot().getX()); - nextMarkArrow.setY(view3D.getPivot().getY()); - nextMarkArrow.setZ(view3D.getPivot().getZ() + 15); - nextMarkArrow.setHeading(headingToMark.degrees()); - } - }; - arrowToNextMark.start(); + nextMarkController.show3d(); +// viewSubjects.add(nextMarkArrow); +// final VisualiserBoat boat; +// try { +// boat = visualiserRace.getVisualiserRaceState().getBoat(subject3D.getSourceID()); +// } catch (BoatNotFoundException e) { +// e.printStackTrace(); +// return; +// } +// arrowToNextMark = new AnimationTimer() { +// @Override +// public void handle(long now) { +// CompoundMark target = boat.getCurrentLeg().getEndCompoundMark(); +// Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate()); +// +// nextMarkArrow.setX(view3D.getPivot().getX()); +// nextMarkArrow.setY(view3D.getPivot().getY()); +// nextMarkArrow.setZ(view3D.getPivot().getZ() + 15); +// nextMarkArrow.setHeading(headingToMark.degrees()); +// } +// }; +// arrowToNextMark.start(); } private void removeThirdPersonAnnotations() { - viewSubjects.remove(nextMarkArrow); - if (arrowToNextMark != null) { - arrowToNextMark.stop(); - } - + nextMarkController.show2d(); } /** diff --git a/racevisionGame/src/main/resources/visualiser/scenes/newRaceView.fxml b/racevisionGame/src/main/resources/visualiser/scenes/newRaceView.fxml index 76195416..0f044a14 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/newRaceView.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/newRaceView.fxml @@ -22,7 +22,7 @@ - + @@ -35,6 +35,13 @@ + + + + + + + diff --git a/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml b/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml new file mode 100644 index 00000000..d9971567 --- /dev/null +++ b/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From bf6282c69706a4500cd7f3bf6d70abc20775b58e Mon Sep 17 00:00:00 2001 From: Joseph Date: Sun, 24 Sep 2017 17:28:13 +1300 Subject: [PATCH 02/16] 3D arrow added for zoomed view. Shows relative direction to mark. #story[1299] --- .../Controllers/NextMarkController.java | 57 ++++++++++++++++++- .../Controllers/RaceViewController.java | 1 - .../resources/visualiser/scenes/nextMark.fxml | 31 ++++++---- 3 files changed, 75 insertions(+), 14 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java b/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java index 001a1a60..fdff5046 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/NextMarkController.java @@ -2,16 +2,25 @@ package visualiser.Controllers; import com.interactivemesh.jfx.importer.stl.StlMeshImporter; import javafx.animation.AnimationTimer; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.fxml.FXML; +import javafx.geometry.Point3D; +import javafx.scene.AmbientLight; +import javafx.scene.control.Label; import javafx.scene.layout.Pane; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.Cylinder; import javafx.scene.shape.MeshView; +import javafx.scene.shape.Shape3D; +import javafx.scene.transform.Rotate; import shared.model.Bearing; import shared.model.CompoundMark; import shared.model.GPSCoordinate; +import visualiser.layout.Subject3D; +import visualiser.layout.View3D; import visualiser.model.VisualiserBoat; import java.net.URL; @@ -20,13 +29,16 @@ import java.util.Observer; public class NextMarkController { private @FXML StackPane arrowStackPane2d; + private @FXML StackPane arrowStackPane3d; private @FXML Pane pane2d; private @FXML Pane pane3d; + private @FXML Label nextMarkLabel; private VisualiserBoat boat; public void initialiseArrowView(VisualiserBoat boat) { this.boat = boat; + this.nextMarkLabel.setVisible(false); pane2d.setVisible(true); pane3d.setVisible(false); initialise2dArrowView(); @@ -46,13 +58,36 @@ public class NextMarkController { } private void initialise3dArrowView() { + ObservableList viewSubjects = FXCollections.observableArrayList(); URL asset = this.getClass().getClassLoader().getResource("assets/arrow V1.0.4.stl"); StlMeshImporter importer = new StlMeshImporter(); importer.read(asset); MeshView arrow = new MeshView(importer.getImport()); - PhongMaterial arrowMat = new PhongMaterial(Color.RED); + PhongMaterial arrowMat = new PhongMaterial(Color.GREEN); arrow.setMaterial(arrowMat); + + AmbientLight ambientLight = new AmbientLight(Color.web("#777777")); + ambientLight.setLightOn(true); + + arrow.setScaleX(50); + arrow.setScaleY(50); + arrow.setScaleZ(300); + arrow.setRotationAxis(new Point3D(1,0,0)); + + arrowStackPane3d.getChildren().add(arrow); + arrowStackPane3d.getChildren().add(ambientLight); + + AnimationTimer arrow3d = new AnimationTimer() { + @Override + public void handle(long now) { + arrow.getTransforms().clear(); + double zRotation = calculateZRotate(); + arrow.setRotate(calculateXRotate(zRotation)); + arrow.getTransforms().add(new Rotate(zRotation, new Point3D(0, 0, 1))); + } + }; + arrow3d.start(); } public void show2d() { @@ -64,4 +99,24 @@ public class NextMarkController { pane2d.setVisible(false); pane3d.setVisible(true); } + + private double calculateZRotate() { + CompoundMark target = boat.getCurrentLeg().getEndCompoundMark(); + Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate()); + return -headingToMark.degrees() + boat.getBearing().degrees(); + } + + private double calculateXRotate(double zRotation) { + if (zRotation > 360) { + zRotation -=360; + } else if (zRotation < 0) { + zRotation += 360; + } + + if (zRotation > 180) { + zRotation = 360 - zRotation; + } + + return 90 - 20 * Math.cos(Math.toRadians(zRotation)); + } } diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java index 29a5bf89..94c169e4 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java @@ -229,7 +229,6 @@ public class RaceViewController extends Controller { try { nextMarkController.initialiseArrowView(race.getVisualiserRaceState().getBoat(race.getVisualiserRaceState().getPlayerBoatID())); - System.out.println("hi"); } catch (BoatNotFoundException e) { e.printStackTrace(); } diff --git a/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml b/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml index d9971567..d26e20f7 100644 --- a/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml +++ b/racevisionGame/src/main/resources/visualiser/scenes/nextMark.fxml @@ -1,15 +1,18 @@ - - - - - - - - + + + + + + + + + + + - + @@ -22,10 +25,10 @@ - + -