The boat is now viewable in top down view (60 degrees for isometric) and the race is playable #story[1261]

main
Fan-Wu Yang 8 years ago
parent 18a689b110
commit 7bad0e53ff

@ -17,8 +17,10 @@ import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.MeshView;
import javafx.scene.shape.Sphere;
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;
@ -29,6 +31,7 @@ import visualiser.gameController.Keys.ControlKey;
import visualiser.layout.Subject3D;
import visualiser.layout.View3D;
import visualiser.model.*;
import visualiser.utils.GPSConverter;
import java.io.IOException;
import java.net.URL;
@ -175,7 +178,7 @@ public class RaceController extends Controller {
}
private void initialiseView3D(VisualiserRaceEvent race) {
int scale = 5000;
int scale = 1;
ObservableList<Subject3D> subjects = FXCollections.observableArrayList();
@ -184,39 +187,59 @@ public class RaceController extends Controller {
importer.read(asset);
view3D = new View3D();
view3D.setDistance(100);
view3D.setDistance(1050);
view3D.setYaw(0);
view3D.setPitch(20);
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);
view3D.setItems(subjects);
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(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);
}
for(VisualiserBoat boat: race.getVisualiserRaceState().getBoats()) {
Subject3D subject = new Subject3D(new MeshView(importer.getImport()));
MeshView mesh = new MeshView(importer.getImport());
Subject3D subject = new Subject3D(mesh);
subjects.add(subject);
AnimationTimer trackBoat = new AnimationTimer() {
@Override
public void handle(long now) {
subject.setHeading(boat.getBearing().degrees());
subject.setX(boat.getPosition().getLongitude() * scale);
subject.setZ(boat.getPosition().getLatitude()* scale);
// 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()) {
view3D.updatePivot(subject.getPosition());
//view3D.updatePivot(subject.getPosition());
}
view3D.setYaw(boat.getBearing().degrees());
//view3D.setYaw(boat.getBearing().degrees());
}
};
trackBoat.start();
}
view3D.updatePivot(new Translate(250, 0, 210));
}

@ -33,6 +33,9 @@ public class Subject3D {
this.heading = new Rotate(0, Rotate.Y_AXIS);
this.mesh.getTransforms().addAll(position, heading, new Rotate(90, Rotate.X_AXIS), new Rotate(180, Rotate.Y_AXIS));
this.position.xProperty().addListener(((observable, oldValue, newValue) -> System.out.println("Boat x: " + newValue)));
this.position.yProperty().addListener(((observable, oldValue, newValue) -> System.out.println("Boat y: " + newValue)));
this.position.zProperty().addListener(((observable, oldValue, newValue) -> System.out.println("Boat z: " + newValue)));
}
public Shape3D getMesh() {

@ -2,6 +2,7 @@ package visualiser.layout;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.SubScene;
@ -77,7 +78,7 @@ public class View3D extends Pane {
// Set up view frustum
nearClip = 0.1;
farClip = 1000.0;
farClip = 3000.0;
camera.setNearClip(nearClip);
camera.setFarClip(farClip);
@ -87,7 +88,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);
//camera.setTranslateZ(-1000);
centerCamera();
this.camera = camera;
return camera;
@ -118,6 +119,13 @@ public class View3D extends Pane {
this.pivot.setY(pivot.getY());
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
@ -141,4 +149,13 @@ 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);
}
}

@ -0,0 +1,91 @@
package visualiser.utils;
import shared.model.GPSCoordinate;
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){
this.longRight = longRight;
this.longLeft = longLeft;
this.latBottom = latBottom;
this.latTop = latTop;
this.paneWidth = (int)paneWidth;
this.paneHeight = (int)paneHeight;
}
/**
* Converts GPS coordinates to coordinates for container.
* It is assumed that the provided GPSCoordinate will always be within the GPSCoordinate boundaries of the RaceMap.
*
* @param lat GPS latitude
* @param lon GPS longitude
* @return GraphCoordinate (pair of doubles)
* @see GraphCoordinate
*/
private GraphCoordinate convertGPS(double lat, double lon) {
//Calculate the width/height, in gps coordinates, of the map.
double longWidth = longRight - longLeft;
double latHeight = latBottom - latTop;
//Calculate the distance between the specified coordinate and the edge of the map.
double longDelta = lon - longLeft;
double latDelta = lat - latTop;
//Calculate the proportion along horizontally, from the left, the coordinate should be.
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);
//Calculate the x and y pixel coordinates.
//We take the complement of latProportion to flip it.
int x = (int) (longProportion * smallerDimension);
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);
//We therefore "center" the coordinates along this larger dimension, by adding half of the extra pixels.
if (paneWidth > paneHeight) {
x += extraPixels / 2;
} else {
y += extraPixels / 2;
}
//Finally, create the GraphCoordinate.
GraphCoordinate graphCoordinate = new GraphCoordinate(x, y);
return graphCoordinate;
}
/**
* Converts the GPS Coordinate to GraphCoordinate.
* It is assumed that the provided GPSCoordinate will always be within the GPSCoordinate boundaries of the RaceMap.
*
* @param coordinate GPSCoordinate representation of Latitude and Longitude.
* @return GraphCoordinate that the GPS is coordinates are to be displayed on the map.
* @see GraphCoordinate
* @see GPSCoordinate
*/
public GraphCoordinate convertGPS(GPSCoordinate coordinate) {
return convertGPS(coordinate.getLatitude(), coordinate.getLongitude());
}
}
Loading…
Cancel
Save