Added scroll-wheel zooming

- Race pane listens to scroll delta and sets View3D distance accordingly
- GPSConverter has more applicable property names for infinite 3D

#story[1190]
main
Connor Taylor-Brown 8 years ago
parent 7bad0e53ff
commit 54baf4f884

@ -12,8 +12,8 @@ import javafx.scene.chart.LineChart;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.Sphere;
@ -21,8 +21,6 @@ import javafx.scene.transform.Translate;
import javafx.util.Callback;
import network.Messages.Enums.RaceStatusEnum;
import shared.dataInput.RaceDataSource;
import shared.exceptions.BoatNotFoundException;
import shared.exceptions.MarkNotFoundException;
import shared.model.Leg;
import shared.model.Mark;
import visualiser.app.App;
@ -35,7 +33,6 @@ import visualiser.utils.GPSConverter;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.logging.Level;
@ -75,7 +72,7 @@ public class RaceController extends Controller {
@FXML private GridPane canvasBase;
@FXML private SplitPane race;
@FXML private SplitPane racePane;
/**
* This is the pane we place the actual arrow control inside of.
@ -103,7 +100,7 @@ public class RaceController extends Controller {
infoTableShow = true;
// Initialise keyboard handler
race.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
racePane.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
String codeString = event.getCode().toString();
if (codeString.equals("TAB")){toggleTable();}
@ -129,7 +126,7 @@ public class RaceController extends Controller {
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK) {
parent.endEvent();
race.setVisible(false);
racePane.setVisible(false);
App.app.showMainStage(App.getStage());
}
} else {
@ -138,7 +135,7 @@ public class RaceController extends Controller {
alert.setContentText("Do you wish to quit the race?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK) {
race.setVisible(false);
racePane.setVisible(false);
App.app.showMainStage(App.getStage());
}
}
@ -180,7 +177,7 @@ public class RaceController extends Controller {
private void initialiseView3D(VisualiserRaceEvent race) {
int scale = 1;
ObservableList<Subject3D> subjects = FXCollections.observableArrayList();
viewSubjects = FXCollections.observableArrayList();
URL asset = HostController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl");
StlMeshImporter importer = new StlMeshImporter();
@ -190,45 +187,35 @@ public class RaceController extends Controller {
view3D.setDistance(1050);
view3D.setYaw(0);
view3D.setPitch(60);
//view3D.rotateCamera(-90, 1, 0, 0);
//view3D.updatePosition(0, 200, 0);
RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource();
double lat1 = raceData.getMapTopLeft().getLatitude();
double long1 = raceData.getMapTopLeft().getLongitude();
double lat2 = raceData.getMapBottomRight().getLatitude();
double long2 = raceData.getMapBottomRight().getLongitude();
System.out.println(view3D.getWidth());
System.out.println(view3D.getHeight());
final GPSConverter gpsConverter = new GPSConverter(lat1, long1, lat2, long2, (int)450, (int)450);
final GPSConverter gpsConverter = new GPSConverter(lat1, long1, lat2, long2, 450, 450);
view3D.setItems(subjects);
view3D.setItems(viewSubjects);
canvasBase.getChildren().add(0, view3D);
for(Mark mark: race.getVisualiserRaceState().getMarks()) {
Subject3D subject = new Subject3D(new Sphere(5));
// subject.setX(mark.getPosition().getLongitude() * scale);
// subject.setZ(mark.getPosition().getLatitude()* scale);
subject.setX(gpsConverter.convertGPS(mark.getPosition()).getX() * scale);
subject.setZ(gpsConverter.convertGPS(mark.getPosition()).getY() * scale);
subjects.add(subject);
viewSubjects.add(subject);
}
for(VisualiserBoat boat: race.getVisualiserRaceState().getBoats()) {
MeshView mesh = new MeshView(importer.getImport());
Subject3D subject = new Subject3D(mesh);
subjects.add(subject);
viewSubjects.add(subject);
AnimationTimer trackBoat = new AnimationTimer() {
@Override
public void handle(long now) {
subject.setHeading(boat.getBearing().degrees());
// subject.setHeading(0);
// subject.setX(boat.getPosition().getLongitude() * scale);
// subject.setZ(boat.getPosition().getLatitude()* scale);
double x = gpsConverter.convertGPS(boat.getPosition()).getX() * scale;
//System.out.println(x);
subject.setX(x);
subject.setZ(gpsConverter.convertGPS(boat.getPosition()).getY() * scale);
if(boat.getSourceID() == race.getVisualiserRaceState().getPlayerBoatID()) {
@ -240,6 +227,10 @@ public class RaceController extends Controller {
trackBoat.start();
}
view3D.updatePivot(new Translate(250, 0, 210));
racePane.setOnScroll(e -> {
view3D.updateDistance(e.getDeltaY());
});
}
@ -422,7 +413,7 @@ public class RaceController extends Controller {
initialiseRace();
//Display this controller.
race.setVisible(true);
racePane.setVisible(true);
}
/**
@ -430,7 +421,7 @@ public class RaceController extends Controller {
* @param boats boats there are in the race.
*/
public void finishRace(ObservableList<VisualiserBoat> boats) {
race.setVisible(false);
racePane.setVisible(false);
parent.enterFinish(boats);
}
@ -471,7 +462,7 @@ public class RaceController extends Controller {
//Return to main screen if we lose connection.
if (!visualiserRace.getServerConnection().isAlive()) {
race.setVisible(false);
racePane.setVisible(false);
//parent.enterTitle();
try {
App.app.showMainStage(App.getStage());
@ -493,10 +484,10 @@ public class RaceController extends Controller {
* toggles if the info table is shown
*/
private void toggleTable() {
double tablePercent = 1 - (boatPlacingColumn.getPrefWidth() + boatTeamColumn.getPrefWidth() + boatMarkColumn.getPrefWidth() + boatSpeedColumn.getPrefWidth())/race.getWidth();
double tablePercent = 1 - (boatPlacingColumn.getPrefWidth() + boatTeamColumn.getPrefWidth() + boatMarkColumn.getPrefWidth() + boatSpeedColumn.getPrefWidth())/racePane.getWidth();
if (infoTableShow){
race.setDividerPositions(tablePercent);
racePane.setDividerPositions(tablePercent);
arrowPane.setScaleX(0.5);
arrowPane.setScaleY(0.5);
@ -504,7 +495,7 @@ public class RaceController extends Controller {
arrowPane.setTranslateY(0 - arrowPane.getScene().getHeight()/4);
}else{
race.setDividerPositions(1);
racePane.setDividerPositions(1);
arrowPane.setScaleX(1);
arrowPane.setScaleY(1);

@ -51,8 +51,6 @@ public class View3D extends Pane {
*/
private Rotate pitch;
private PerspectiveCamera camera;
/**
* Default constructor for View3D. Sets up Scene and PerspectiveCamera.
*/
@ -88,9 +86,7 @@ public class View3D extends Pane {
yaw = new Rotate(0, Rotate.Y_AXIS);
pitch = new Rotate(0, Rotate.X_AXIS);
camera.getTransforms().addAll(pivot, yaw, pitch, distance);
centerCamera();
this.camera = camera;
return camera;
}
@ -120,12 +116,6 @@ public class View3D extends Pane {
this.pivot.setZ(pivot.getZ());
}
public void updatePosition(double x, double y, double z) {
this.distance.setX(x);
this.distance.setY(y);
this.distance.setZ(z);
}
/**
* Set distance of camera from pivot
* @param distance in units
@ -134,6 +124,10 @@ public class View3D extends Pane {
this.distance.setZ(-distance);
}
public void updateDistance(double delta) {
this.distance.setZ(this.distance.getZ() - delta);
}
/**
* Set angle of camera from z-axis along ground
* @param yaw in degrees
@ -149,13 +143,4 @@ public class View3D extends Pane {
public void setPitch(double pitch) {
this.pitch.setAngle(-pitch);
}
public void centerCamera(){
}
public void rotateCamera(double angle, double x, double y, double z){
camera.setRotationAxis(new Point3D(x, y, z));
camera.setRotate(-90);
}
}

@ -7,20 +7,27 @@ import visualiser.model.GraphCoordinate;
* Created by fwy13 on 7/09/17.
*/
public class GPSConverter {
double longRight;
double longLeft;
double latBottom;
double latTop;
int paneWidth;
int paneHeight;
public GPSConverter(double latTop, double longLeft, double latBottom, double longRight, double paneWidth, double paneHeight){
private double longRight;
private double longLeft;
private double latBottom;
private double latTop;
/**
* Conversion factor from longitude to view units
*/
private double longitudeFactor;
/**
* Conversion factor from latitude to view units
*/
private double latitudeFactor;
public GPSConverter(double latTop, double longLeft, double latBottom, double longRight, double longitudeFactor, double latitudeFactor){
this.longRight = longRight;
this.longLeft = longLeft;
this.latBottom = latBottom;
this.latTop = latTop;
this.paneWidth = (int)paneWidth;
this.paneHeight = (int)paneHeight;
this.longitudeFactor = (int)longitudeFactor;
this.latitudeFactor = (int)latitudeFactor;
}
/**
@ -46,11 +53,9 @@ public class GPSConverter {
double longProportion = longDelta / longWidth;
//Calculate the proportion along vertically, from the top, the coordinate should be.
double latProportion = latDelta / latHeight;
//System.out.println(latProportion + " " + longProportion);
//Check which pixel dimension of our map is smaller. We use this to ensure that any rendered stuff retains its correct aspect ratio, and that everything is visible on screen.
int smallerDimension = Math.min(paneWidth, paneHeight);
//Check which metric dimension of our map is smaller. We use this to ensure that any rendered stuff retains its correct aspect ratio, and that everything is visible on screen.
double smallerDimension = Math.min(longitudeFactor, latitudeFactor);
//Calculate the x and y pixel coordinates.
//We take the complement of latProportion to flip it.
@ -58,12 +63,12 @@ public class GPSConverter {
int y = (int) (latProportion * smallerDimension);
//Because we try to maintain the correct aspect ratio, we will end up with "spare" pixels along the larger dimension (e.g., width 800, height 600, 200 extra pixels along width).
int extraPixels = Math.abs(paneWidth - paneHeight);
double extraDistance = Math.abs(longitudeFactor - latitudeFactor);
//We therefore "center" the coordinates along this larger dimension, by adding half of the extra pixels.
if (paneWidth > paneHeight) {
x += extraPixels / 2;
if (longitudeFactor > latitudeFactor) {
x += extraDistance / 2;
} else {
y += extraPixels / 2;
y += extraDistance / 2;
}

@ -22,7 +22,7 @@
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Font?>
<SplitPane fx:id="race" dividerPositions="1.0" prefHeight="431.0" prefWidth="610.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.RaceController">
<SplitPane fx:id="racePane" dividerPositions="1.0" prefHeight="431.0" prefWidth="610.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.RaceController">
<items>
<GridPane fx:id="canvasBase">
<columnConstraints>

Loading…
Cancel
Save