mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Merge remote-tracking branch 'origin/story1266_3d_model_factory' into story1266_3d_model_factory
This commit is contained in:
@@ -5,7 +5,6 @@ import javafx.application.Application;
|
|||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.SceneAntialiasing;
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
@@ -69,7 +68,7 @@ public class App extends Application {
|
|||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
Parent root = FXMLLoader.load(getClass().getResource("/views/StartScreenView.fxml"));
|
Parent root = FXMLLoader.load(getClass().getResource("/views/StartScreenView.fxml"));
|
||||||
primaryStage.setTitle("Party Parrots at Sea");
|
primaryStage.setTitle("Party Parrots at Sea");
|
||||||
Scene scene = new Scene(root, 1530, 960, false, SceneAntialiasing.BALANCED);
|
Scene scene = new Scene(root, 1530, 960);
|
||||||
scene.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
scene.getStylesheets().add(getClass().getResource("/css/master.css").toString());
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
// primaryStage.setMaxWidth(1530);
|
// primaryStage.setMaxWidth(1530);
|
||||||
|
|||||||
@@ -451,6 +451,19 @@ public class GameView extends Pane {
|
|||||||
raceBorder.getPoints().setAll(boundaryPoints);
|
raceBorder.getPoints().setAll(boundaryPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rescales the race to the size of the window.
|
||||||
|
*
|
||||||
|
* @param limitingCoordinates the set of geo points that contains the extremities of the race.
|
||||||
|
*/
|
||||||
|
private void rescaleRace(List<GeoPoint> limitingCoordinates) {
|
||||||
|
//Check is called once to avoid unnecessarily change the course limits once the race is running
|
||||||
|
findMinMaxPoint(limitingCoordinates);
|
||||||
|
double minLonToMaxLon = scaleRaceExtremities();
|
||||||
|
calculateReferencePointLocation(minLonToMaxLon);
|
||||||
|
// drawGoogleMap();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces all tokens in the course with those passed in
|
* Replaces all tokens in the course with those passed in
|
||||||
*
|
*
|
||||||
@@ -487,18 +500,6 @@ public class GameView extends Pane {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Rescales the race to the size of the window.
|
|
||||||
*
|
|
||||||
* @param limitingCoordinates the set of geo points that contains the extremities of the race.
|
|
||||||
*/
|
|
||||||
private void rescaleRace(List<GeoPoint> limitingCoordinates) {
|
|
||||||
//Check is called once to avoid unnecessarily change the course limits once the race is running
|
|
||||||
findMinMaxPoint(limitingCoordinates);
|
|
||||||
double minLonToMaxLon = scaleRaceExtremities();
|
|
||||||
calculateReferencePointLocation(minLonToMaxLon);
|
|
||||||
// drawGoogleMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setSelectedBoat(BoatObject bo, Boolean isSelected) {
|
private void setSelectedBoat(BoatObject bo, Boolean isSelected) {
|
||||||
if (this.selectedBoat == bo && !isSelected) {
|
if (this.selectedBoat == bo && !isSelected) {
|
||||||
|
|||||||
@@ -1,13 +1,40 @@
|
|||||||
package seng302.visualiser;
|
package seng302.visualiser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javafx.animation.AnimationTimer;
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.geometry.Point2D;
|
||||||
import javafx.geometry.Point3D;
|
import javafx.geometry.Point3D;
|
||||||
import javafx.scene.*;
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.ParallelCamera;
|
||||||
|
import javafx.scene.SceneAntialiasing;
|
||||||
|
import javafx.scene.SubScene;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.paint.PhongMaterial;
|
import javafx.scene.paint.Paint;
|
||||||
import javafx.scene.shape.Sphere;
|
import javafx.scene.shape.Polygon;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
import javafx.scene.transform.Rotate;
|
import javafx.scene.transform.Rotate;
|
||||||
|
import javafx.scene.transform.Scale;
|
||||||
import javafx.scene.transform.Translate;
|
import javafx.scene.transform.Translate;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
import seng302.gameServer.messages.RoundingSide;
|
||||||
|
import seng302.model.ClientYacht;
|
||||||
|
import seng302.model.GeoPoint;
|
||||||
|
import seng302.model.Limit;
|
||||||
|
import seng302.model.mark.CompoundMark;
|
||||||
|
import seng302.model.mark.Corner;
|
||||||
|
import seng302.model.mark.Mark;
|
||||||
|
import seng302.utilities.GeoUtility;
|
||||||
|
import seng302.visualiser.fxObjects.assets_2D.AnnotationBox;
|
||||||
|
import seng302.visualiser.fxObjects.assets_2D.BoatObject;
|
||||||
|
import seng302.visualiser.fxObjects.assets_2D.CourseBoundary;
|
||||||
|
import seng302.visualiser.fxObjects.assets_2D.Gate;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||||
import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
||||||
|
|
||||||
@@ -22,97 +49,458 @@ public class GameView3D {
|
|||||||
|
|
||||||
Group root3D;
|
Group root3D;
|
||||||
SubScene view;
|
SubScene view;
|
||||||
PerspectiveCamera camera;
|
ParallelCamera camera;
|
||||||
Group gameObjects;
|
Group gameObjects;
|
||||||
|
|
||||||
|
private double bufferSize = 0;
|
||||||
|
private double canvasWidth = 200;
|
||||||
|
private double canvasHeight = 200;
|
||||||
|
private boolean horizontalInversion = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private double distanceScaleFactor;
|
||||||
|
private ScaleDirection scaleDirection;
|
||||||
|
private GeoPoint minLatPoint, minLonPoint, maxLatPoint, maxLonPoint;
|
||||||
|
private double referencePointX, referencePointY;
|
||||||
|
private double metersPerPixelX, metersPerPixelY;
|
||||||
|
|
||||||
|
final double SCALE_DELTA = 1.1;
|
||||||
|
|
||||||
|
private Text fpsDisplay = new Text();
|
||||||
|
private Polygon raceBorder = new CourseBoundary();
|
||||||
|
|
||||||
|
/* Note that if either of these is null then values for it have not been added and the other
|
||||||
|
should be used as the limits of the map. */
|
||||||
|
private List<Limit> borderPoints;
|
||||||
|
private Map<Mark, Group> markerObjects;
|
||||||
|
|
||||||
|
private Map<ClientYacht, BoatObject> boatObjects = new HashMap<>();
|
||||||
|
private Map<ClientYacht, AnnotationBox> annotations = new HashMap<>();
|
||||||
|
private BoatObject selectedBoat = null;
|
||||||
|
private Group annotationsGroup = new Group();
|
||||||
|
private Group wakesGroup = new Group();
|
||||||
|
private Group boatObjectGroup = new Group();
|
||||||
|
private Group trails = new Group();
|
||||||
|
private Group markers = new Group();
|
||||||
|
private Group tokens = new Group();
|
||||||
|
private List<CompoundMark> course = new ArrayList<>();
|
||||||
|
private List<Node> mapTokens;
|
||||||
|
|
||||||
|
private ImageView mapImage = new ImageView();
|
||||||
|
|
||||||
|
//FRAME RATE
|
||||||
|
|
||||||
|
private AnimationTimer timer;
|
||||||
|
private int NUM_SAMPLES = 10;
|
||||||
|
private final long[] frameTimes = new long[NUM_SAMPLES];
|
||||||
|
private Double frameRate = 60.0;
|
||||||
|
private int frameTimeIndex = 0;
|
||||||
|
private boolean arrayFilled = false;
|
||||||
|
private ClientYacht playerYacht;
|
||||||
|
private double windDir = 0.0;
|
||||||
|
|
||||||
|
double scaleFactor = 1;
|
||||||
|
|
||||||
|
private enum ScaleDirection {
|
||||||
|
HORIZONTAL,
|
||||||
|
VERTICAL
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public GameView3D () {
|
public GameView3D () {
|
||||||
camera = new PerspectiveCamera(true);
|
// camera = new PerspectiveCamera(true);
|
||||||
|
camera = new ParallelCamera();
|
||||||
camera.getTransforms().addAll(
|
camera.getTransforms().addAll(
|
||||||
new Translate(0,0, -DEFAULT_CAMERA_DEPTH)
|
new Translate(0,0, -DEFAULT_CAMERA_DEPTH)
|
||||||
);
|
);
|
||||||
camera.setFarClip(Double.MAX_VALUE);
|
camera.setFarClip(Double.MAX_VALUE);
|
||||||
camera.setNearClip(0.1);
|
camera.setNearClip(0.1);
|
||||||
camera.setFieldOfView(FOV);
|
// camera.setFieldOfView(FOV);
|
||||||
gameObjects = new Group();
|
gameObjects = new Group();
|
||||||
|
gameObjects.getTransforms().add(new Scale(4,4,4));
|
||||||
root3D = new Group(camera, gameObjects);
|
root3D = new Group(camera, gameObjects);
|
||||||
view = new SubScene(
|
view = new SubScene(
|
||||||
root3D, 1000, 1000, true, SceneAntialiasing.BALANCED
|
root3D, 1000, 1000, true, SceneAntialiasing.BALANCED
|
||||||
);
|
);
|
||||||
view.setCamera(camera);
|
view.setCamera(camera);
|
||||||
Sphere s = new Sphere(1);
|
view.setFill(Color.SKYBLUE);
|
||||||
s.setMaterial(new PhongMaterial(Color.RED));
|
camera.getTransforms().add(new Rotate(30, new Point3D(1,0,0)));
|
||||||
Sphere left = new Sphere(1);
|
camera.setLayoutX(camera.getLayoutX()-400);
|
||||||
left.setMaterial(new PhongMaterial(Color.LEMONCHIFFON));
|
camera.setLayoutY(camera.getLayoutX()-600);
|
||||||
left.getTransforms().add(new Translate(-Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0, 0));
|
// gameObjects.getChildren().addAll(raceBorder, markers, tokens);
|
||||||
Sphere right = new Sphere(1);
|
gameObjects.getChildren().addAll(
|
||||||
right.setMaterial(new PhongMaterial(Color.ROSYBROWN));
|
ModelFactory.importModel(ModelType.OCEAN).getAssets(), markers
|
||||||
right.getTransforms().add(new Translate(Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0, 0));
|
);
|
||||||
Sphere top = new Sphere(1);
|
|
||||||
top.setMaterial(new PhongMaterial(Color.TEAL));
|
|
||||||
top.getTransforms().add(new Translate(0,-Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0));
|
|
||||||
Sphere bottom = new Sphere(1);
|
|
||||||
bottom.setMaterial(new PhongMaterial(Color.BLANCHEDALMOND));
|
|
||||||
bottom.getTransforms().add(new Translate(0, Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0));
|
|
||||||
|
|
||||||
Node boat = ModelFactory.boatGameView(BoatMeshType.DINGHY, Color.BLUE).getAssets();
|
// Sphere s = new Sphere(1);
|
||||||
Node boat2 = ModelFactory.boatGameView(BoatMeshType.DINGHY, Color.BROWN).getAssets();
|
// s.setMaterial(new PhongMaterial(Color.RED));
|
||||||
boat2.getTransforms().add(new Translate(0,20, 0));
|
// Sphere left = new Sphere(1);
|
||||||
Node boat3 = ModelFactory.boatGameView(BoatMeshType.DINGHY, Color.RED).getAssets();
|
// left.setMaterial(new PhongMaterial(Color.LEMONCHIFFON));
|
||||||
boat3.getTransforms().add(new Translate(0,-20, 0));
|
// left.getTransforms().add(new Translate(-Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0, 0));
|
||||||
|
// Sphere right = new Sphere(1);
|
||||||
|
// right.setMaterial(new PhongMaterial(Color.ROSYBROWN));
|
||||||
|
// right.getTransforms().add(new Translate(Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0, 0));
|
||||||
|
// Sphere top = new Sphere(1);
|
||||||
|
// top.setMaterial(new PhongMaterial(Color.TEAL));
|
||||||
|
// top.getTransforms().add(new Translate(0,-Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0));
|
||||||
|
// Sphere bottom = new Sphere(1);
|
||||||
|
// bottom.setMaterial(new PhongMaterial(Color.BLANCHEDALMOND));
|
||||||
|
// bottom.getTransforms().add(new Translate(0, Math.tan(Math.toRadians(FOV / 2)) * DEFAULT_CAMERA_DEPTH, 0));
|
||||||
|
//
|
||||||
|
// Node boat = ModelFactory.boatGameView(BoatMeshType.DINGHY, Color.BLUE).getAssets();
|
||||||
|
// Node boat2 = ModelFactory.boatGameView(BoatMeshType.DINGHY, Color.BROWN).getAssets();
|
||||||
|
// boat2.getTransforms().add(new Translate(0,20, 0));
|
||||||
|
// Node boat3 = ModelFactory.boatGameView(BoatMeshType.DINGHY, Color.RED).getAssets();
|
||||||
|
// boat3.getTransforms().add(new Translate(0,-20, 0));
|
||||||
|
//
|
||||||
|
// Node sMarker = ModelFactory.importModel(ModelType.START_MARKER).getAssets();
|
||||||
|
// sMarker.getTransforms().add(0, new Translate(30, 30, 0));
|
||||||
|
//
|
||||||
|
// Node fMarker = ModelFactory.importModel(ModelType.FINISH_MARKER).getAssets();
|
||||||
|
// fMarker.getTransforms().add(0, new Translate(30, -30, 0));
|
||||||
|
//
|
||||||
|
// Node marker = ModelFactory.importModel(ModelType.PLAIN_MARKER).getAssets();
|
||||||
|
// marker.getTransforms().add(0, new Translate(30, 0, 0));
|
||||||
|
//
|
||||||
|
// Node coin = ModelFactory.importModel(ModelType.VELOCITY_COIN).getAssets();
|
||||||
|
// coin.setTranslateX(coin.getTranslateX() - 30);
|
||||||
|
//
|
||||||
|
// gameObjects.getChildren().addAll(
|
||||||
|
// ModelFactory.importModel(ModelType.OCEAN).getAssets(),
|
||||||
|
// s, left, right, top, bottom,
|
||||||
|
// boat, boat2, boat3,
|
||||||
|
// sMarker, fMarker, marker,
|
||||||
|
// coin
|
||||||
|
// );
|
||||||
|
|
||||||
Node sMarker = ModelFactory.importModel(ModelType.START_MARKER).getAssets();
|
|
||||||
sMarker.getTransforms().add(0, new Translate(30, 30, 0));
|
|
||||||
|
|
||||||
Node fMarker = ModelFactory.importModel(ModelType.FINISH_MARKER).getAssets();
|
|
||||||
fMarker.getTransforms().add(0, new Translate(30, -30, 0));
|
|
||||||
|
|
||||||
Node marker = ModelFactory.importModel(ModelType.PLAIN_MARKER).getAssets();
|
|
||||||
marker.getTransforms().add(0, new Translate(30, 0, 0));
|
|
||||||
|
|
||||||
Node coin = ModelFactory.importModel(ModelType.VELOCITY_COIN).getAssets();
|
|
||||||
coin.setTranslateX(coin.getTranslateX() - 30);
|
|
||||||
|
|
||||||
gameObjects.getChildren().addAll(s, left, right, top, bottom, boat, boat2, boat3, sMarker, fMarker, marker, coin);
|
|
||||||
view.sceneProperty().addListener((obs, old, scene) -> {
|
view.sceneProperty().addListener((obs, old, scene) -> {
|
||||||
if (scene!=null)
|
if (scene != null) {
|
||||||
enableCameraMovement(scene);
|
scene.addEventHandler(KeyEvent.KEY_PRESSED, this::cameraMovement);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableCameraMovement(Scene s) {
|
public void updateCourse(List<CompoundMark> newCourse, List<Corner> sequence) {
|
||||||
s.setOnKeyPressed(event -> {
|
markerObjects = new HashMap<>();
|
||||||
switch (event.getCode()) {
|
|
||||||
case UP:
|
for (Corner corner : sequence) { //Makes course out of all compound marks.
|
||||||
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(1,0,0)));
|
for (CompoundMark compoundMark : newCourse) {
|
||||||
break;
|
if (corner.getCompoundMarkID() == compoundMark.getId()) {
|
||||||
case DOWN:
|
course.add(compoundMark);
|
||||||
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(1,0,0)));
|
}
|
||||||
break;
|
|
||||||
case LEFT:
|
|
||||||
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(0,1,0)));
|
|
||||||
break;
|
|
||||||
case RIGHT:
|
|
||||||
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(0,1,0)));
|
|
||||||
break;
|
|
||||||
case SPACE:
|
|
||||||
camera.getTransforms().addAll(new Translate(0, 0, 0.75));
|
|
||||||
break;
|
|
||||||
case Z:
|
|
||||||
camera.getTransforms().addAll(new Translate(0, 0, -0.75));
|
|
||||||
break;
|
|
||||||
case W:
|
|
||||||
camera.getTransforms().addAll(new Translate(0, 1, 0));
|
|
||||||
break;
|
|
||||||
case S:
|
|
||||||
camera.getTransforms().addAll(new Translate(0, -1, 0));
|
|
||||||
break;
|
|
||||||
case A:
|
|
||||||
camera.getTransforms().addAll(new Translate(-1, 0, 0));
|
|
||||||
break;
|
|
||||||
case D:
|
|
||||||
camera.getTransforms().addAll(new Translate(1, 0, 0));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 16/08/17 Updating mark roundings here. It should not happen here. Nor should it be done this way.
|
||||||
|
for (Corner corner : sequence){
|
||||||
|
CompoundMark compoundMark = course.get(corner.getSeqID() - 1);
|
||||||
|
compoundMark.setRoundingSide(
|
||||||
|
RoundingSide.getRoundingSide(corner.getRounding())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Gate> gates = new ArrayList<>();
|
||||||
|
Paint colour = Color.BLACK;
|
||||||
|
//Creates new markers
|
||||||
|
for (CompoundMark cMark : newCourse) {
|
||||||
|
//Set start and end colour
|
||||||
|
// if (cMark.getId() == sequence.get(0).getCompoundMarkID()) {
|
||||||
|
// colour = Color.GREEN;
|
||||||
|
// } else if (cMark.getId() == sequence.get(sequence.size() - 1).getCompoundMarkID()) {
|
||||||
|
// colour = Color.RED;
|
||||||
|
// }
|
||||||
|
//Create mark dots
|
||||||
|
for (Mark mark : cMark.getMarks()) {
|
||||||
|
makeAndBindMarker(mark);
|
||||||
|
}
|
||||||
|
// //Create gate line
|
||||||
|
// if (cMark.isGate()) {
|
||||||
|
// for (int i = 1; i < cMark.getMarks().size(); i++) {
|
||||||
|
// gates.add(
|
||||||
|
// makeAndBindGate(
|
||||||
|
// markerObjects.get(cMark.getSubMark(i)),
|
||||||
|
// markerObjects.get(cMark.getSubMark(i + 1)),
|
||||||
|
// colour
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// colour = Color.BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scale race to markers if there is no border.
|
||||||
|
if (borderPoints == null) {
|
||||||
|
rescaleRace(new ArrayList<>(markerObjects.keySet()));
|
||||||
|
}
|
||||||
|
//Move the Markers to initial position.
|
||||||
|
markerObjects.forEach(((mark, marker) -> {
|
||||||
|
Point2D p2d = findScaledXY(mark.getLat(), mark.getLng());
|
||||||
|
System.out.println(mark.toString() + " " + p2d.toString());
|
||||||
|
marker.setLayoutX(p2d.getX());
|
||||||
|
marker.setLayoutY(p2d.getY());
|
||||||
|
}));
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
markers.getChildren().clear();
|
||||||
|
markers.getChildren().addAll(gates);
|
||||||
|
markers.getChildren().addAll(markerObjects.values());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new Marker and binds it's position to the given Mark.
|
||||||
|
*
|
||||||
|
* @param observableMark The mark to bind the marker to.
|
||||||
|
*/
|
||||||
|
private void makeAndBindMarker(Mark observableMark) {
|
||||||
|
|
||||||
|
Group marker = ModelFactory.importModel(ModelType.PLAIN_MARKER).getAssets();
|
||||||
|
|
||||||
|
markerObjects.put(observableMark, marker);
|
||||||
|
observableMark.addPositionListener((mark, lat, lon) -> {
|
||||||
|
Point2D p2d = findScaledXY(lat, lon);
|
||||||
|
markerObjects.get(mark).setLayoutX(p2d.getX());
|
||||||
|
markerObjects.get(mark).setLayoutY(p2d.getY());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the class variables minLatPoint, maxLatPoint, minLonPoint, maxLonPoint to the point with
|
||||||
|
* the leftmost point, rightmost point, southern most point and northern most point
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
private void findMinMaxPoint(List<GeoPoint> points) {
|
||||||
|
List<GeoPoint> sortedPoints = new ArrayList<>(points);
|
||||||
|
sortedPoints.sort(Comparator.comparingDouble(GeoPoint::getLat));
|
||||||
|
minLatPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng());
|
||||||
|
GeoPoint maxLat = sortedPoints.get(sortedPoints.size() - 1);
|
||||||
|
maxLatPoint = new GeoPoint(maxLat.getLat(), maxLat.getLng());
|
||||||
|
|
||||||
|
sortedPoints.sort(Comparator.comparingDouble(GeoPoint::getLng));
|
||||||
|
minLonPoint = new GeoPoint(sortedPoints.get(0).getLat(), sortedPoints.get(0).getLng());
|
||||||
|
GeoPoint maxLon = sortedPoints.get(sortedPoints.size() - 1);
|
||||||
|
maxLonPoint = new GeoPoint(maxLon.getLat(), maxLon.getLng());
|
||||||
|
if (maxLonPoint.getLng() - minLonPoint.getLng() > 180) {
|
||||||
|
horizontalInversion = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the location of a reference point, this is always the point with minimum latitude,
|
||||||
|
* in relation to the canvas.
|
||||||
|
*
|
||||||
|
* @param minLonToMaxLon The horizontal distance between the point of minimum longitude to
|
||||||
|
* maximum longitude.
|
||||||
|
*/
|
||||||
|
private void calculateReferencePointLocation(double minLonToMaxLon) {
|
||||||
|
GeoPoint referencePoint = minLatPoint;
|
||||||
|
double referenceAngle;
|
||||||
|
|
||||||
|
if (scaleDirection == ScaleDirection.HORIZONTAL) {
|
||||||
|
referenceAngle = Math.abs(
|
||||||
|
GeoUtility.getBearingRad(referencePoint, minLonPoint)
|
||||||
|
);
|
||||||
|
referencePointX =
|
||||||
|
-100 + distanceScaleFactor * Math.sin(referenceAngle) * GeoUtility
|
||||||
|
.getDistance(referencePoint, minLonPoint);
|
||||||
|
referenceAngle = Math.abs(GeoUtility.getDistance(referencePoint, maxLatPoint));
|
||||||
|
referencePointY = -100 + canvasHeight - (bufferSize + bufferSize);
|
||||||
|
referencePointY -= distanceScaleFactor * Math.cos(referenceAngle) * GeoUtility
|
||||||
|
.getDistance(referencePoint, maxLatPoint);
|
||||||
|
referencePointY = referencePointY / 2;
|
||||||
|
referencePointY += bufferSize;
|
||||||
|
referencePointY += distanceScaleFactor * Math.cos(referenceAngle) * GeoUtility
|
||||||
|
.getDistance(referencePoint, maxLatPoint);
|
||||||
|
} else {
|
||||||
|
referencePointY = -100 + canvasHeight - bufferSize;
|
||||||
|
referenceAngle = Math.abs(
|
||||||
|
Math.toRadians(
|
||||||
|
GeoUtility.getDistance(referencePoint, minLonPoint)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
referencePointX = -100 + bufferSize;
|
||||||
|
referencePointX += distanceScaleFactor * Math.sin(referenceAngle) * GeoUtility
|
||||||
|
.getDistance(referencePoint, minLonPoint);
|
||||||
|
referencePointX +=
|
||||||
|
((canvasWidth - (bufferSize + bufferSize)) - (minLonToMaxLon * distanceScaleFactor))
|
||||||
|
/ 2;
|
||||||
|
}
|
||||||
|
if (horizontalInversion) {
|
||||||
|
referencePointX = -100 + canvasWidth - bufferSize - (referencePointX - bufferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the scale factor necessary to fit all race markers within the onscreen map and assigns
|
||||||
|
* it to distanceScaleFactor Returns the max horizontal distance of the map.
|
||||||
|
*/
|
||||||
|
private double scaleRaceExtremities() {
|
||||||
|
|
||||||
|
double vertAngle = Math.abs(
|
||||||
|
GeoUtility.getBearingRad(minLatPoint, maxLatPoint)
|
||||||
|
);
|
||||||
|
double vertDistance =
|
||||||
|
Math.cos(vertAngle) * GeoUtility.getDistance(minLatPoint, maxLatPoint);
|
||||||
|
double horiAngle = Math.abs(
|
||||||
|
GeoUtility.getBearingRad(minLonPoint, maxLonPoint)
|
||||||
|
);
|
||||||
|
if (horiAngle <= (Math.PI / 2)) {
|
||||||
|
horiAngle = (Math.PI / 2) - horiAngle;
|
||||||
|
} else {
|
||||||
|
horiAngle = horiAngle - (Math.PI / 2);
|
||||||
|
}
|
||||||
|
double horiDistance =
|
||||||
|
Math.cos(horiAngle) * GeoUtility.getDistance(minLonPoint, maxLonPoint);
|
||||||
|
|
||||||
|
double vertScale = (canvasHeight - (bufferSize + bufferSize)) / vertDistance;
|
||||||
|
|
||||||
|
if ((horiDistance * vertScale) > (canvasWidth - (bufferSize + bufferSize))) {
|
||||||
|
distanceScaleFactor = (canvasWidth - (bufferSize + bufferSize)) / horiDistance;
|
||||||
|
scaleDirection = ScaleDirection.HORIZONTAL;
|
||||||
|
} else {
|
||||||
|
distanceScaleFactor = vertScale;
|
||||||
|
scaleDirection = ScaleDirection.VERTICAL;
|
||||||
|
}
|
||||||
|
return horiDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point2D findScaledXY(GeoPoint unscaled) {
|
||||||
|
return findScaledXY(unscaled.getLat(), unscaled.getLng());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point2D findScaledXY(double unscaledLat, double unscaledLon) {
|
||||||
|
double distanceFromReference;
|
||||||
|
double angleFromReference;
|
||||||
|
double xAxisLocation = referencePointX;
|
||||||
|
double yAxisLocation = referencePointY;
|
||||||
|
|
||||||
|
angleFromReference = GeoUtility.getBearingRad(
|
||||||
|
minLatPoint, new GeoPoint(unscaledLat, unscaledLon)
|
||||||
|
);
|
||||||
|
distanceFromReference = GeoUtility.getDistance(
|
||||||
|
minLatPoint, new GeoPoint(unscaledLat, unscaledLon)
|
||||||
|
);
|
||||||
|
if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) {
|
||||||
|
xAxisLocation += Math
|
||||||
|
.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
|
||||||
|
yAxisLocation -= Math
|
||||||
|
.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference);
|
||||||
|
} else if (angleFromReference >= 0) {
|
||||||
|
angleFromReference = angleFromReference - Math.PI / 2;
|
||||||
|
xAxisLocation += Math
|
||||||
|
.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference);
|
||||||
|
yAxisLocation += Math
|
||||||
|
.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
|
||||||
|
} else if (angleFromReference < 0 && angleFromReference >= -Math.PI / 2) {
|
||||||
|
angleFromReference = Math.abs(angleFromReference);
|
||||||
|
xAxisLocation -= Math
|
||||||
|
.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
|
||||||
|
yAxisLocation -= Math
|
||||||
|
.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference);
|
||||||
|
} else {
|
||||||
|
angleFromReference = Math.abs(angleFromReference) - Math.PI / 2;
|
||||||
|
xAxisLocation -= Math
|
||||||
|
.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference);
|
||||||
|
yAxisLocation += Math
|
||||||
|
.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference);
|
||||||
|
}
|
||||||
|
if (horizontalInversion) {
|
||||||
|
xAxisLocation = canvasWidth - bufferSize - (xAxisLocation - bufferSize);
|
||||||
|
}
|
||||||
|
return new Point2D(xAxisLocation, yAxisLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cameraMovement(KeyEvent event) {
|
||||||
|
switch (event.getCode()) {
|
||||||
|
case UP:
|
||||||
|
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(1,0,0)));
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(1,0,0)));
|
||||||
|
break;
|
||||||
|
case LEFT:
|
||||||
|
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(0,1,0)));
|
||||||
|
break;
|
||||||
|
case RIGHT:
|
||||||
|
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(0,1,0)));
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
camera.getTransforms().addAll(new Translate(0, 0, 1.5));
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
camera.getTransforms().addAll(new Translate(0, 0, -1.5));
|
||||||
|
break;
|
||||||
|
case W:
|
||||||
|
camera.getTransforms().addAll(new Translate(0, 1, 0));
|
||||||
|
break;
|
||||||
|
case S:
|
||||||
|
camera.getTransforms().addAll(new Translate(0, -1, 0));
|
||||||
|
break;
|
||||||
|
case A:
|
||||||
|
camera.getTransforms().addAll(new Translate(-1, 0, 0));
|
||||||
|
break;
|
||||||
|
case D:
|
||||||
|
camera.getTransforms().addAll(new Translate(1, 0, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rescales the race to the size of the window.
|
||||||
|
*
|
||||||
|
* @param limitingCoordinates the set of geo points that contains the extremities of the race.
|
||||||
|
*/
|
||||||
|
private void rescaleRace(List<GeoPoint> limitingCoordinates) {
|
||||||
|
//Check is called once to avoid unnecessarily change the course limits once the race is running
|
||||||
|
findMinMaxPoint(limitingCoordinates);
|
||||||
|
double minLonToMaxLon = scaleRaceExtremities();
|
||||||
|
calculateReferencePointLocation(minLonToMaxLon);
|
||||||
|
// drawGoogleMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws all the boats.
|
||||||
|
* @param yachts The yachts to set in the race
|
||||||
|
*/
|
||||||
|
public void setBoats(List<ClientYacht> yachts) {
|
||||||
|
BoatObject newBoat;
|
||||||
|
final List<Group> wakes = new ArrayList<>();
|
||||||
|
for (ClientYacht clientYacht : yachts) {
|
||||||
|
Color colour = clientYacht.getColour();
|
||||||
|
newBoat = new BoatObject();
|
||||||
|
// newBoat.addSelectedBoatListener(this::setSelectedBoat);
|
||||||
|
newBoat.setFill(colour);
|
||||||
|
boatObjects.put(clientYacht, newBoat);
|
||||||
|
// createAndBindAnnotationBox(clientYacht, colour);
|
||||||
|
// wakesGroup.getChildren().add(newBoat.getWake());
|
||||||
|
// wakes.add(newBoat.getWake());
|
||||||
|
boatObjectGroup.getChildren().add(newBoat);
|
||||||
|
// trails.getChildren().add(newBoat.getTrail());
|
||||||
|
|
||||||
|
clientYacht.addLocationListener((boat, lat, lon, heading, sailIn, velocity) -> {
|
||||||
|
BoatObject bo = boatObjects.get(boat);
|
||||||
|
Point2D p2d = findScaledXY(lat, lon);
|
||||||
|
bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir);
|
||||||
|
// annotations.get(boat).setLocation(p2d.getX(), p2d.getY());
|
||||||
|
bo.setTrajectory(
|
||||||
|
heading,
|
||||||
|
velocity,
|
||||||
|
metersPerPixelX,
|
||||||
|
metersPerPixelY);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// annotationsGroup.getChildren().addAll(annotations.values());
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
gameObjects.getChildren().addAll(boatObjectGroup);
|
||||||
|
// gameObjects.addAll(trails);
|
||||||
|
// gameObjects.addAll(wakes);
|
||||||
|
// gameObjects.addAll(annotationsGroup);
|
||||||
|
// gameObjects.addAll(boatObjectGroup);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ import seng302.model.RaceState;
|
|||||||
import seng302.model.mark.CompoundMark;
|
import seng302.model.mark.CompoundMark;
|
||||||
import seng302.model.mark.Mark;
|
import seng302.model.mark.Mark;
|
||||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||||
import seng302.visualiser.GameView;
|
import seng302.visualiser.GameView3D;
|
||||||
import seng302.visualiser.controllers.annotations.Annotation;
|
|
||||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationController;
|
import seng302.visualiser.controllers.annotations.ImportantAnnotationController;
|
||||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationDelegate;
|
import seng302.visualiser.controllers.annotations.ImportantAnnotationDelegate;
|
||||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationsState;
|
import seng302.visualiser.controllers.annotations.ImportantAnnotationsState;
|
||||||
@@ -86,7 +85,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
private Map<Integer, ClientYacht> participants;
|
private Map<Integer, ClientYacht> participants;
|
||||||
private Map<Integer, CompoundMark> markers;
|
private Map<Integer, CompoundMark> markers;
|
||||||
private RaceXMLData courseData;
|
private RaceXMLData courseData;
|
||||||
private GameView gameView;
|
private GameView3D gameView;
|
||||||
private RaceState raceState;
|
private RaceState raceState;
|
||||||
|
|
||||||
private Timeline timerTimeline;
|
private Timeline timerTimeline;
|
||||||
@@ -140,32 +139,32 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
});
|
});
|
||||||
|
|
||||||
updateOrder(raceState.getPlayerPositions());
|
updateOrder(raceState.getPlayerPositions());
|
||||||
gameView = new GameView();
|
gameView = new GameView3D();
|
||||||
gameView.setFrameRateFXText(fpsDisplay);
|
// gameView.setFrameRateFXText(fpsDisplay);
|
||||||
Platform.runLater(() -> contentAnchorPane.getChildren().add(0, gameView));
|
Platform.runLater(() -> contentAnchorPane.getChildren().add(0, gameView.getAssets()));
|
||||||
gameView.setBoats(new ArrayList<>(participants.values()));
|
gameView.setBoats(new ArrayList<>(participants.values()));
|
||||||
gameView.updateBorder(raceData.getCourseLimit());
|
// gameView.updateBorder(raceData.getCourseLimit());
|
||||||
gameView.updateTokens(raceData.getTokens());
|
// gameView.updateTokens(raceData.getTokens());
|
||||||
gameView.updateCourse(
|
gameView.updateCourse(
|
||||||
new ArrayList<>(raceData.getCompoundMarks().values()), raceData.getMarkSequence()
|
new ArrayList<>(raceData.getCompoundMarks().values()), raceData.getMarkSequence()
|
||||||
);
|
|
||||||
gameView.enableZoom();
|
|
||||||
gameView.setBoatAsPlayer(player);
|
|
||||||
gameView.startRace();
|
|
||||||
|
|
||||||
raceState.addCollisionListener(gameView::drawCollision);
|
|
||||||
raceState.windDirectionProperty().addListener((obs, oldDirection, newDirection) -> {
|
|
||||||
gameView.setWindDir(newDirection.doubleValue());
|
|
||||||
Platform.runLater(() -> updateWindDirection(newDirection.doubleValue()));
|
|
||||||
});
|
|
||||||
raceState.windSpeedProperty().addListener((obs, oldSpeed, newSpeed) ->
|
|
||||||
Platform.runLater(() -> updateWindSpeed(newSpeed.doubleValue()))
|
|
||||||
);
|
);
|
||||||
Platform.runLater(() -> {
|
// gameView.enableZoom();
|
||||||
updateWindDirection(raceState.windDirectionProperty().doubleValue());
|
// gameView.setBoatAsPlayer(player);
|
||||||
updateWindSpeed(raceState.getWindSpeed());
|
// gameView.startRace();
|
||||||
});
|
|
||||||
gameView.setWindDir(raceState.windDirectionProperty().doubleValue());
|
// raceState.addCollisionListener(gameView::drawCollision);
|
||||||
|
// raceState.windDirectionProperty().addListener((obs, oldDirection, newDirection) -> {
|
||||||
|
// gameView.setWindDir(newDirection.doubleValue());
|
||||||
|
// Platform.runLater(() -> updateWindDirection(newDirection.doubleValue()));
|
||||||
|
// });
|
||||||
|
// raceState.windSpeedProperty().addListener((obs, oldSpeed, newSpeed) ->
|
||||||
|
// Platform.runLater(() -> updateWindSpeed(newSpeed.doubleValue()))
|
||||||
|
// );
|
||||||
|
// Platform.runLater(() -> {
|
||||||
|
// updateWindDirection(raceState.windDirectionProperty().doubleValue());
|
||||||
|
// updateWindSpeed(raceState.getWindSpeed());
|
||||||
|
// });
|
||||||
|
// gameView.setWindDir(raceState.windDirectionProperty().doubleValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,9 +206,9 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initialiseFPSCheckBox() {
|
private void initialiseFPSCheckBox() {
|
||||||
toggleFps.selectedProperty().addListener((obs, oldVal, newVal) ->
|
// toggleFps.selectedProperty().addListener((obs, oldVal, newVal) ->
|
||||||
gameView.setFPSVisibility(toggleFps.isSelected())
|
// gameView.setFPSVisibility(toggleFps.isSelected())
|
||||||
);
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialiseAnnotationSlider() {
|
private void initialiseAnnotationSlider() {
|
||||||
@@ -550,7 +549,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
//Null check is if the listener is fired but nothing selected
|
//Null check is if the listener is fired but nothing selected
|
||||||
yachtSelectionComboBox.valueProperty().addListener((obs, lastSelection, selectedBoat) -> {
|
yachtSelectionComboBox.valueProperty().addListener((obs, lastSelection, selectedBoat) -> {
|
||||||
if (selectedBoat != null) {
|
if (selectedBoat != null) {
|
||||||
gameView.selectBoat(selectedBoat);
|
// gameView.selectBoat(selectedBoat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -582,31 +581,31 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setAnnotations(Integer annotationLevel) {
|
private void setAnnotations(Integer annotationLevel) {
|
||||||
switch (annotationLevel) {
|
// switch (annotationLevel) {
|
||||||
// No Annotations
|
// // No Annotations
|
||||||
case 0:
|
// case 0:
|
||||||
gameView.setAnnotationVisibilities(
|
// gameView.setAnnotationVisibilities(
|
||||||
false, false, false, false, false, false
|
// false, false, false, false, false, false
|
||||||
);
|
// );
|
||||||
break;
|
// break;
|
||||||
// Important Annotations
|
// // Important Annotations
|
||||||
case 1:
|
// case 1:
|
||||||
gameView.setAnnotationVisibilities(
|
// gameView.setAnnotationVisibilities(
|
||||||
importantAnnotations.getAnnotationState(Annotation.NAME),
|
// importantAnnotations.getAnnotationState(Annotation.NAME),
|
||||||
importantAnnotations.getAnnotationState(Annotation.SPEED),
|
// importantAnnotations.getAnnotationState(Annotation.SPEED),
|
||||||
importantAnnotations.getAnnotationState(Annotation.ESTTIMETONEXTMARK),
|
// importantAnnotations.getAnnotationState(Annotation.ESTTIMETONEXTMARK),
|
||||||
importantAnnotations.getAnnotationState(Annotation.LEGTIME),
|
// importantAnnotations.getAnnotationState(Annotation.LEGTIME),
|
||||||
importantAnnotations.getAnnotationState(Annotation.TRACK),
|
// importantAnnotations.getAnnotationState(Annotation.TRACK),
|
||||||
importantAnnotations.getAnnotationState(Annotation.WAKE)
|
// importantAnnotations.getAnnotationState(Annotation.WAKE)
|
||||||
);
|
// );
|
||||||
break;
|
// break;
|
||||||
// All Annotations
|
// // All Annotations
|
||||||
case 2:
|
// case 2:
|
||||||
gameView.setAnnotationVisibilities(
|
// gameView.setAnnotationVisibilities(
|
||||||
true, true, true, true, true, true
|
// true, true, true, true, true, true
|
||||||
);
|
// );
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -630,7 +629,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateRaceData (RaceXMLData raceData) {
|
public void updateRaceData (RaceXMLData raceData) {
|
||||||
gameView.updateBorder(raceData.getCourseLimit());
|
// gameView.updateBorder(raceData.getCourseLimit());
|
||||||
gameView.updateTokens(raceData.getTokens());
|
// gameView.updateTokens(raceData.getTokens());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.geometry.Point3D;
|
|
||||||
import javafx.scene.AmbientLight;
|
import javafx.scene.AmbientLight;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
@@ -103,9 +102,9 @@ public class BoatObject extends Group {
|
|||||||
private void initChildren(double... points) {
|
private void initChildren(double... points) {
|
||||||
boatPoly = makeBoatPolygon();
|
boatPoly = makeBoatPolygon();
|
||||||
boatPoly.getAssets().getTransforms().addAll(
|
boatPoly.getAssets().getTransforms().addAll(
|
||||||
new Rotate(-40, new Point3D(1,0,0)),
|
// new Rotate(-40, new Point3D(1,0,0)),
|
||||||
rotation,
|
rotation
|
||||||
new Rotate(-90, new Point3D(0,0,1))
|
// new Rotate(-90, new Point3D(0,0,1))
|
||||||
);
|
);
|
||||||
boatPoly.getAssets().getTransforms().add(new Scale(5, 5, 5));
|
boatPoly.getAssets().getTransforms().add(new Scale(5, 5, 5));
|
||||||
// boatPoly.setDrawMode(DrawMode.FILL);
|
// boatPoly.setDrawMode(DrawMode.FILL);
|
||||||
@@ -219,21 +218,21 @@ public class BoatObject extends Group {
|
|||||||
rotateTo(rotation, sailIn, windDir);
|
rotateTo(rotation, sailIn, windDir);
|
||||||
boatPoly.getAssets().setLayoutX(x);
|
boatPoly.getAssets().setLayoutX(x);
|
||||||
boatPoly.getAssets().setLayoutY(y);
|
boatPoly.getAssets().setLayoutY(y);
|
||||||
if (sailIn) {
|
// if (sailIn) {
|
||||||
// sail.getPoints().clear();
|
//// sail.getPoints().clear();
|
||||||
// sail.getPoints().addAll(0.0, 0.0, 4.0, 1.5, 8.0, 3.0, 12.0, 3.5, 16.0, 3.0, 20.0, 1.5, 24.0, 0.0);
|
//// sail.getPoints().addAll(0.0, 0.0, 4.0, 1.5, 8.0, 3.0, 12.0, 3.5, 16.0, 3.0, 20.0, 1.5, 24.0, 0.0);
|
||||||
// sail.getPoints().addAll(0.0, 0.0, 24.0, 0.0);
|
//// sail.getPoints().addAll(0.0, 0.0, 24.0, 0.0);
|
||||||
sail.setLayoutX(x);
|
// sail.setLayoutX(x);
|
||||||
sail.setLayoutY(y);
|
// sail.setLayoutY(y);
|
||||||
} else {
|
// } else {
|
||||||
animateSail();
|
//// animateSail();
|
||||||
sail.setLayoutX(x);
|
// sail.setLayoutX(x);
|
||||||
sail.setLayoutY(y);
|
// sail.setLayoutY(y);
|
||||||
}
|
// }
|
||||||
wake.setLayoutX(x);
|
// wake.setLayoutX(x);
|
||||||
wake.setLayoutY(y);
|
// wake.setLayoutY(y);
|
||||||
});
|
});
|
||||||
wake.setRotation(rotation, velocity);
|
// wake.setRotation(rotation, velocity);
|
||||||
// rotateTo(rotation);
|
// rotateTo(rotation);
|
||||||
// boatPoly.setLayoutX(x);
|
// boatPoly.setLayoutX(x);
|
||||||
// boatPoly.setLayoutY(y);
|
// boatPoly.setLayoutY(y);
|
||||||
@@ -263,7 +262,7 @@ public class BoatObject extends Group {
|
|||||||
|
|
||||||
private void rotateTo(double heading, boolean sailsIn, double windDir) {
|
private void rotateTo(double heading, boolean sailsIn, double windDir) {
|
||||||
rotation.setAngle(heading);
|
rotation.setAngle(heading);
|
||||||
if (sailsIn) {
|
if (!sailsIn) {
|
||||||
boatPoly.showSail();
|
boatPoly.showSail();
|
||||||
Double sailWindOffset = 30.0;
|
Double sailWindOffset = 30.0;
|
||||||
Double upwindAngleLimit = 15.0;
|
Double upwindAngleLimit = 15.0;
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ import javafx.animation.AnimationTimer;
|
|||||||
import javafx.geometry.Point3D;
|
import javafx.geometry.Point3D;
|
||||||
import javafx.scene.AmbientLight;
|
import javafx.scene.AmbientLight;
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.paint.PhongMaterial;
|
import javafx.scene.paint.PhongMaterial;
|
||||||
|
import javafx.scene.shape.Circle;
|
||||||
import javafx.scene.shape.MeshView;
|
import javafx.scene.shape.MeshView;
|
||||||
import javafx.scene.transform.Rotate;
|
import javafx.scene.transform.Rotate;
|
||||||
import javafx.scene.transform.Scale;
|
import javafx.scene.transform.Scale;
|
||||||
import seng302.model.token.TokenType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory class for creating 3D models of boats.
|
* Factory class for creating 3D models of boats.
|
||||||
@@ -55,7 +54,8 @@ public class ModelFactory {
|
|||||||
public static BoatModel boatGameView(BoatMeshType boatType, Color primaryColour) {
|
public static BoatModel boatGameView(BoatMeshType boatType, Color primaryColour) {
|
||||||
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
|
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
|
||||||
boatAssets.getTransforms().setAll(
|
boatAssets.getTransforms().setAll(
|
||||||
new Scale(0.5, 0.5, 0.5)
|
new Rotate(-90, new Point3D(0,0,1)),
|
||||||
|
new Scale(0.2, 0.2, 0.2)
|
||||||
);
|
);
|
||||||
return new BoatModel(boatAssets, null, boatType);
|
return new BoatModel(boatAssets, null, boatType);
|
||||||
}
|
}
|
||||||
@@ -79,9 +79,14 @@ public class ModelFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Model importModel(ModelType tokenType) {
|
public static Model importModel(ModelType tokenType) {
|
||||||
ColModelImporter importer = new ColModelImporter();
|
Group assets;
|
||||||
importer.read(ModelFactory.class.getResource("/meshes/" + tokenType.filename));
|
if (tokenType.filename == null) {
|
||||||
Group assets = new Group(importer.getImport());
|
assets = new Group();
|
||||||
|
} else {
|
||||||
|
ColModelImporter importer = new ColModelImporter();
|
||||||
|
importer.read(ModelFactory.class.getResource("/meshes/" + tokenType.filename));
|
||||||
|
assets = new Group(importer.getImport());
|
||||||
|
}
|
||||||
switch (tokenType) {
|
switch (tokenType) {
|
||||||
case VELOCITY_COIN:
|
case VELOCITY_COIN:
|
||||||
return makeCoinPickup(assets);
|
return makeCoinPickup(assets);
|
||||||
@@ -89,6 +94,8 @@ public class ModelFactory {
|
|||||||
case PLAIN_MARKER:
|
case PLAIN_MARKER:
|
||||||
case START_MARKER:
|
case START_MARKER:
|
||||||
return makeMarker(assets);
|
return makeMarker(assets);
|
||||||
|
case OCEAN:
|
||||||
|
return makeOcean(assets);
|
||||||
default:
|
default:
|
||||||
return new Model(assets, null);
|
return new Model(assets, null);
|
||||||
}
|
}
|
||||||
@@ -121,4 +128,14 @@ public class ModelFactory {
|
|||||||
area.getTransforms().add(new Rotate(90, new Point3D(1, 0, 0)));
|
area.getTransforms().add(new Rotate(90, new Point3D(1, 0, 0)));
|
||||||
return new Model(area, null);
|
return new Model(area, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Model makeOcean(Group group) {
|
||||||
|
// group.setScaleY(Double.MAX_VALUE);
|
||||||
|
// group.setScaleX(Double.MAX_VALUE);
|
||||||
|
// group.getTransforms().add(new Rotate(90, new Point3D(1, 0, 0)));
|
||||||
|
Circle ocean = new Circle(0,0,1000, Color.DEEPSKYBLUE);
|
||||||
|
ocean.setStroke(Color.TRANSPARENT);
|
||||||
|
group.getChildren().add(ocean);
|
||||||
|
return new Model(group, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package seng302.visualiser.fxObjects.assets_3D;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum for models. Values should be the name of the file and files should be .dae files with texture
|
* Enum for models. Values should be the name of the file and files should be .dae files with texture
|
||||||
* information included.
|
* information included. Can be null in which case assets are assumed to be empty.
|
||||||
*/
|
*/
|
||||||
public enum ModelType {
|
public enum ModelType {
|
||||||
|
|
||||||
@@ -10,7 +10,10 @@ public enum ModelType {
|
|||||||
FINISH_MARKER ("finish_marker.dae"),
|
FINISH_MARKER ("finish_marker.dae"),
|
||||||
START_MARKER ("start_marker.dae"),
|
START_MARKER ("start_marker.dae"),
|
||||||
PLAIN_MARKER ("plain_marker.dae"),
|
PLAIN_MARKER ("plain_marker.dae"),
|
||||||
MARK_AREA ("mark_area.dae");
|
MARK_AREA ("mark_area.dae"),
|
||||||
|
OCEAN (null),
|
||||||
|
BORDER_PYLON (null),
|
||||||
|
BORDER_BARRIER (null);
|
||||||
|
|
||||||
final String filename;
|
final String filename;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user