diff --git a/racevisionGame/pom.xml b/racevisionGame/pom.xml
index 41157414..4a3c65a4 100644
--- a/racevisionGame/pom.xml
+++ b/racevisionGame/pom.xml
@@ -46,14 +46,17 @@
15.0
-
-
org.geotools
gt-referencing
9.0
+
+ JavaInteractiveMesh
+ STLImporter
+ 0.7
+
@@ -72,7 +75,11 @@
http://download.osgeo.org/webdav/geotools/
-
+
+ interactivemesh
+ Interactive Mesh
+ http://umbrasheep.com:8888/repository/internal/
+
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java
index 1609e700..008276ef 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java
@@ -1,21 +1,29 @@
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.scene.control.TextField;
+import javafx.scene.control.Alert;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.SplitPane;
+import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.GridPane;
+import javafx.scene.shape.Box;
+import javafx.scene.shape.Mesh;
+import javafx.scene.shape.MeshView;
+import javafx.scene.shape.Shape3D;
+import javafx.scene.transform.Rotate;
import mock.app.Event;
-import org.xml.sax.SAXException;
import mock.exceptions.EventConstructionException;
-import shared.exceptions.InvalidBoatDataException;
-import shared.exceptions.InvalidRaceDataException;
-import shared.exceptions.InvalidRegattaDataException;
-import shared.exceptions.XMLReaderException;
+import visualiser.model.View3D;
-import javax.xml.bind.JAXBException;
-import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.net.Socket;
import java.net.URL;
+import java.util.Optional;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -26,27 +34,70 @@ import java.util.logging.Logger;
public class HostController extends Controller {
- @FXML
- TextField gameNameField;
+// @FXML
+// TextField gameNameField;
+//
+// @FXML
+// TextField hostNameField;
@FXML
- TextField hostNameField;
+ private ImageView imageView;
@FXML
AnchorPane hostWrapper;
+ @FXML
+ AnchorPane imagePane;
+
+ @FXML
+ SplitPane splitPane;
+
+ @FXML
+ AnchorPane specPane;
+
+ @FXML
+ GridPane playerContainer;
+
private Event game;
+ private View3D view3D;
@Override
public void initialize(URL location, ResourceBundle resources) {
+ ObservableList shapes = FXCollections.observableArrayList();
+
+ view3D = new View3D();
+ view3D.setItems(shapes);
+ playerContainer.add(view3D, 0,0);
+
+ URL asset = HostController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl");
+
+ StlMeshImporter importer = new StlMeshImporter();
+ importer.read(asset);
+ MeshView mesh = new MeshView(importer.getImport());
+ shapes.add(mesh);
+
+ view3D.setPivot(mesh);
+ view3D.setDistance(50);
+ view3D.setYaw(45);
+ view3D.setPitch(20);
+
+ Rotate rotation = new Rotate(0, Rotate.Y_AXIS);
+ mesh.getTransforms().addAll(rotation, new Rotate(-90, Rotate.X_AXIS));
+
+ AnimationTimer rotate = new AnimationTimer() {
+ @Override
+ public void handle(long now) {
+ rotation.setAngle(rotation.getAngle() + 0.1);
+ }
+ };
+ rotate.start();
}
/**
* Hosts a game
- * @throws IOException if socket cannot be connected to
*/
- public void hostGamePressed() throws IOException{
+ public void hostGamePressed() {
try {
this.game = new Event(false);
connectSocket("localhost", 4942);
@@ -81,12 +132,34 @@ public class HostController extends Controller {
* Hosts a game.
*/
public void hostGame(){
+ splitPane.setResizableWithParent(specPane, false);
+ splitPane.lookupAll(".split-pane-divider").stream().forEach(div -> div.setMouseTransparent(true));
+ imageView.fitWidthProperty().bind(imagePane.widthProperty());
+ imageView.fitHeightProperty().bind(imagePane.heightProperty());
hostWrapper.setVisible(true);
}
+ /**
+ * Menu button pressed. Prompt alert then return to menu
+ */
public void menuBtnPressed(){
- hostWrapper.setVisible(false);
- parent.enterTitle();
+ Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
+ alert.setTitle("Quitting race");
+ alert.setContentText("Do you wish to quit the race?");
+ alert.setHeaderText("You are about to quit the race");
+ Optional result = alert.showAndWait();
+ if(result.get() == ButtonType.OK){
+ hostWrapper.setVisible(false);
+ parent.enterTitle();
+ }
+ }
+
+ /**
+ * Start button pressed. Currently only prints out start
+ */
+ public void startBtnPressed(){
+ //System.out.println("Should start the race. This button is only visible for the host");
+ hostGamePressed();
}
}
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java b/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java
index 07af2b49..d541c531 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/LobbyController.java
@@ -21,7 +21,7 @@ import java.util.ResourceBundle;
public class LobbyController extends Controller {
@FXML
- AnchorPane lobbyWrapper;
+ private AnchorPane lobbyWrapper;
@FXML
private TableView lobbyTable;
@FXML
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java
index 4fcda581..b6a53f0b 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java
@@ -356,7 +356,7 @@ public class RaceController extends Controller {
private void initialiseRaceCanvas(VisualiserRaceEvent race) {
//Create canvas.
- raceCanvas = new ResizableRaceCanvas(race);
+ raceCanvas = new ResizableRaceCanvas(race.getVisualiserRaceState());
//Set properties.
raceCanvas.setMouseTransparent(true);
diff --git a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java
index 32e033c8..5617e3da 100644
--- a/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java
+++ b/racevisionGame/src/main/java/visualiser/Controllers/TitleController.java
@@ -81,7 +81,6 @@ public class TitleController extends Controller {
@Override
public void initialize(URL location, ResourceBundle resources) {
-
}
/**
diff --git a/racevisionGame/src/main/java/visualiser/app/App.java b/racevisionGame/src/main/java/visualiser/app/App.java
index eeae5a5d..31dcae24 100644
--- a/racevisionGame/src/main/java/visualiser/app/App.java
+++ b/racevisionGame/src/main/java/visualiser/app/App.java
@@ -96,15 +96,15 @@ public class App extends Application {
);
updateMessage("Preparing ingredients . . .");
- Thread.sleep(1000);
+ Thread.sleep(200);
for (int i = 0; i < burgerFilling.size(); i++) {
- Thread.sleep(800);
+ Thread.sleep(100);
updateProgress(i + 1, burgerFilling.size());
String nextFilling = burgerFilling.get(i);
addedFilling.add(nextFilling);
updateMessage("Adding the " + nextFilling + " . . .");
}
- Thread.sleep(400);
+ Thread.sleep(100);
updateMessage("Burger's done!");
return addedFilling;
diff --git a/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java b/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java
new file mode 100644
index 00000000..9314f5cd
--- /dev/null
+++ b/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java
@@ -0,0 +1,18 @@
+package visualiser.model;
+
+import com.interactivemesh.jfx.importer.Importer;
+import javafx.scene.layout.Pane;
+
+/**
+ * Created by fwy13 on 29/08/17.
+ */
+public class BoatDisplay3D extends Pane {
+
+
+ public BoatDisplay3D(String filePath){
+ super();
+// Shape3D
+// this.getChildren().add();
+ }
+
+}
diff --git a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java
index fc6a0858..03e86e27 100644
--- a/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java
+++ b/racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java
@@ -39,9 +39,9 @@ public class ResizableRaceCanvas extends ResizableCanvas {
private Image sailsLuff = new Image("/images/sailsLuff.gif", 25, 10, false, false);
/**
- * The race we read data from and draw.
+ * The race state we read data from and draw.
*/
- private VisualiserRaceEvent visualiserRace;
+ private VisualiserRaceState raceState;
private boolean annoName = true;
@@ -56,14 +56,14 @@ public class ResizableRaceCanvas extends ResizableCanvas {
/**
* Constructs a {@link ResizableRaceCanvas} using a given {@link VisualiserRaceEvent}.
- * @param visualiserRace The race that data is read from in order to be drawn.
+ * @param raceState The race state to be drawn.
*/
- public ResizableRaceCanvas(VisualiserRaceEvent visualiserRace) {
+ public ResizableRaceCanvas(VisualiserRaceState raceState) {
super();
- this.visualiserRace = visualiserRace;
+ this.raceState = raceState;
- RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource();
+ RaceDataSource raceData = raceState.getRaceDataSource();
double lat1 = raceData.getMapTopLeft().getLatitude();
double long1 = raceData.getMapTopLeft().getLongitude();
@@ -276,8 +276,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
boat.getCountry(),
boat.getCurrentSpeed(),
this.map.convertGPS(boat.getPosition()),
- boat.getTimeToNextMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()),
- boat.getTimeSinceLastMarkFormatted(this.visualiserRace.getVisualiserRaceState().getRaceClock().getCurrentTime()),
+ boat.getTimeToNextMarkFormatted(raceState.getRaceClock().getCurrentTime()),
+ boat.getTimeSinceLastMarkFormatted(raceState.getRaceClock().getCurrentTime()),
Color.BLACK,
20 );
@@ -291,7 +291,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
*/
private void drawBoats() {
- List boats = new ArrayList<>(visualiserRace.getVisualiserRaceState().getBoats());
+ List boats = new ArrayList<>(raceState.getBoats());
//Sort to ensure we draw boats in consistent order.
boats.sort(Comparator.comparingInt(Boat::getSourceID));
@@ -510,7 +510,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
*/
private void drawMarks() {
- for (Mark mark : new ArrayList<>(visualiserRace.getVisualiserRaceState().getMarks())) {
+ for (Mark mark : new ArrayList<>(raceState.getMarks())) {
drawMark(mark);
}
}
@@ -574,7 +574,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
//Calculate the screen coordinates of the boundary.
- List boundary = new ArrayList<>(visualiserRace.getVisualiserRaceState().getBoundary());
+ List boundary = new ArrayList<>(raceState.getBoundary());
double[] xpoints = new double[boundary.size()];
double[] ypoints = new double[boundary.size()];
@@ -601,8 +601,8 @@ public class ResizableRaceCanvas extends ResizableCanvas {
public void drawRace() {
//Update RaceMap with new GPS values of race.
- this.map.setGPSTopLeft(visualiserRace.getVisualiserRaceState().getRaceDataSource().getMapTopLeft());
- this.map.setGPSBotRight(visualiserRace.getVisualiserRaceState().getRaceDataSource().getMapBottomRight());
+ this.map.setGPSTopLeft(raceState.getRaceDataSource().getMapTopLeft());
+ this.map.setGPSBotRight(raceState.getRaceDataSource().getMapBottomRight());
clear();
@@ -627,7 +627,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
* draws a transparent line around the course that shows the paths boats must travel
*/
public void drawRaceLine(){
- List legs = this.visualiserRace.getVisualiserRaceState().getLegs();
+ List legs = raceState.getLegs();
GPSCoordinate legStartPoint = legs.get(0).getStartCompoundMark().getAverageGPSCoordinate();
GPSCoordinate nextStartPoint;
for (int i = 0; i < legs.size() -1; i++) {
diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/model/View3D.java
new file mode 100644
index 00000000..6affb906
--- /dev/null
+++ b/racevisionGame/src/main/java/visualiser/model/View3D.java
@@ -0,0 +1,145 @@
+package visualiser.model;
+
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.scene.Group;
+import javafx.scene.PerspectiveCamera;
+import javafx.scene.SubScene;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Shape3D;
+import javafx.scene.transform.Rotate;
+import javafx.scene.transform.Translate;
+
+/**
+ * Control for rendering 3D objects visible through a PerspectiveCamera. Implements Adapter Pattern to
+ * interface with camera, and allows clients to add shapes to the scene. All scenes contain sea plane and
+ * sky box, whose textures are set with special methods.
+ */
+public class View3D extends Pane {
+ /**
+ * Observable list of renderable items
+ */
+ private ObservableList items;
+ /**
+ * Rendering container for shapes
+ */
+ private Group world;
+ /**
+ * Near limit of view frustum
+ */
+ private double nearClip;
+ /**
+ * Far limit of view frustum
+ */
+ private double farClip;
+ /**
+ * Position camera pivots around
+ */
+ private Translate pivot;
+ /**
+ * Distance of camera from pivot point
+ */
+ private Translate distance;
+ /**
+ * Angle along ground between z-axis and camera
+ */
+ private Rotate yaw;
+ /**
+ * Angle between ground plane and camera direction
+ */
+ private Rotate pitch;
+
+ /**
+ * Default constructor for View3D. Sets up Scene and PerspectiveCamera.
+ */
+ public View3D() {
+ world = new Group();
+
+ SubScene scene = new SubScene(world, 300, 300);
+ scene.widthProperty().bind(this.widthProperty());
+ scene.heightProperty().bind(this.heightProperty());
+ scene.setFill(Color.BLACK);
+
+ scene.setCamera(buildCamera());
+
+ this.getChildren().add(scene);
+ }
+
+ /**
+ * Sets up camera view frustum and binds transformations
+ * @return perspective camera
+ */
+ private PerspectiveCamera buildCamera() {
+ PerspectiveCamera camera = new PerspectiveCamera(true);
+
+ // Set up view frustum
+ nearClip = 0.1;
+ farClip = 1000.0;
+ camera.setNearClip(nearClip);
+ camera.setFarClip(farClip);
+
+ // Set up transformations
+ pivot = new Translate();
+ distance = new Translate();
+ yaw = new Rotate(0, Rotate.Y_AXIS);
+ pitch = new Rotate(0, Rotate.X_AXIS);
+ camera.getTransforms().addAll(pivot, yaw, pitch, distance);
+
+ return camera;
+ }
+
+ public void setItems(ObservableList items) {
+ this.items = items;
+ this.items.addListener((ListChangeListener super Shape3D>) c -> {
+ while(c.next()) {
+ if (c.wasRemoved() || c.wasAdded()) {
+ for (Shape3D shape : c.getRemoved()) world.getChildren().remove(shape);
+ for (Shape3D shape : c.getAddedSubList()) world.getChildren().add(shape);
+ }
+ }
+ });
+ }
+
+ public void setNearClip(double nearClip) {
+ this.nearClip = nearClip;
+ }
+
+ public void setFarClip(double farClip) {
+ this.farClip = farClip;
+ }
+
+ /**
+ * Set object to centre on camera
+ * @param pivot centred object
+ */
+ public void setPivot(Shape3D pivot) {
+ this.pivot.setX(pivot.getTranslateX());
+ this.pivot.setY(pivot.getTranslateY());
+ this.pivot.setZ(pivot.getTranslateZ());
+ }
+
+ /**
+ * Set distance of camera from pivot
+ * @param distance in units
+ */
+ public void setDistance(double distance) {
+ this.distance.setZ(-distance);
+ }
+
+ /**
+ * Set angle of camera from z-axis along ground
+ * @param yaw in degrees
+ */
+ public void setYaw(double yaw) {
+ this.yaw.setAngle(yaw);
+ }
+
+ /**
+ * Set elevation of camera
+ * @param pitch in degrees
+ */
+ public void setPitch(double pitch) {
+ this.pitch.setAngle(-pitch);
+ }
+}
diff --git a/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl b/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl
new file mode 100644
index 00000000..a952ca77
Binary files /dev/null and b/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl differ
diff --git a/racevisionGame/src/main/resources/visualiser/images/lobby.gif b/racevisionGame/src/main/resources/visualiser/images/lobby.gif
new file mode 100644
index 00000000..c70d8df6
Binary files /dev/null and b/racevisionGame/src/main/resources/visualiser/images/lobby.gif differ
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml
index ced36627..ab14abaf 100644
--- a/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml
+++ b/racevisionGame/src/main/resources/visualiser/scenes/hostgame.fxml
@@ -1,40 +1,44 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml
new file mode 100644
index 00000000..c4198bf3
--- /dev/null
+++ b/racevisionGame/src/main/resources/visualiser/scenes/hostlobby.fxml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/main.fxml b/racevisionGame/src/main/resources/visualiser/scenes/main.fxml
index 074a9b31..7aff44c0 100644
--- a/racevisionGame/src/main/resources/visualiser/scenes/main.fxml
+++ b/racevisionGame/src/main/resources/visualiser/scenes/main.fxml
@@ -7,7 +7,7 @@
-
+
diff --git a/racevisionGame/src/main/resources/visualiser/scenes/title.fxml b/racevisionGame/src/main/resources/visualiser/scenes/title.fxml
index f448a226..255381af 100644
--- a/racevisionGame/src/main/resources/visualiser/scenes/title.fxml
+++ b/racevisionGame/src/main/resources/visualiser/scenes/title.fxml
@@ -1,61 +1,61 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+