diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 008276ef..e7583252 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -11,14 +11,11 @@ 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 mock.exceptions.EventConstructionException; -import visualiser.model.View3D; +import visualiser.layout.Subject3D; +import visualiser.layout.View3D; import java.io.IOException; import java.net.Socket; @@ -64,31 +61,29 @@ public class HostController extends Controller { @Override public void initialize(URL location, ResourceBundle resources) { - ObservableList shapes = FXCollections.observableArrayList(); + ObservableList subjects = FXCollections.observableArrayList(); view3D = new View3D(); - view3D.setItems(shapes); + view3D.setItems(subjects); 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); + Subject3D subject = new Subject3D(new MeshView(importer.getImport())); - view3D.setPivot(mesh); + subjects.add(subject); + + view3D.setPivot(subject); 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); + subject.setHeading(subject.getHeading() + 0.1); } }; rotate.start(); diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index b6a53f0b..9d7e36c9 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -28,6 +28,7 @@ import visualiser.model.*; 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; @@ -185,6 +186,8 @@ public class RaceController extends Controller { //Race canvas. initialiseRaceCanvas(this.visualiserRace); + initialiseView3D(this.visualiserRace); + //Race timezone label. initialiseRaceTimezoneLabel(this.visualiserRace); @@ -196,6 +199,14 @@ public class RaceController extends Controller { raceTimer(); } + private void initialiseView3D(VisualiserRaceEvent race) { + List boats = race.getVisualiserRaceState().getBoats(); + for(VisualiserBoat boat: boats) { + boat.positionProperty().addListener((o, prev, curr) -> { + System.out.println(boat.getCountry() + " is at " + curr.toString()); + }); + } + } /** diff --git a/racevisionGame/src/main/java/visualiser/layout/Subject3D.java b/racevisionGame/src/main/java/visualiser/layout/Subject3D.java new file mode 100644 index 00000000..17736843 --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/layout/Subject3D.java @@ -0,0 +1,72 @@ +package visualiser.layout; + +import javafx.scene.shape.Shape3D; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Translate; + +/** + * Wrapper for controlling the position and heading of rendered 3D models. + */ +public class Subject3D { + /** + * Rendered mesh + */ + private Shape3D mesh; + + /** + * Position translation updated by state listeners + */ + private Translate position; + /** + * Heading rotation updated by state listeners + */ + private Rotate heading; + + /** + * Constructor for view subject wrapper + * @param mesh to be rendered + */ + public Subject3D(Shape3D mesh) { + this.mesh = mesh; + this.position = new Translate(); + this.heading = new Rotate(0, Rotate.Y_AXIS); + + this.mesh.getTransforms().addAll(heading, new Rotate(-90, Rotate.X_AXIS), position); + } + + public Shape3D getMesh() { + return mesh; + } + + public double getX() { + return this.position.getX(); + } + + public double getY() { + return this.position.getY(); + } + + public double getZ() { + return this.position.getZ(); + } + + public void setX(double x) { + this.position.setX(x); + } + + public void setY(double y) { + this.position.setY(y); + } + + public void setZ(double z) { + this.position.setZ(z); + } + + public double getHeading() { + return this.heading.getAngle(); + } + + public void setHeading(double angle) { + this.heading.setAngle(angle); + } +} diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java similarity index 85% rename from racevisionGame/src/main/java/visualiser/model/View3D.java rename to racevisionGame/src/main/java/visualiser/layout/View3D.java index 6affb906..2aae9f1a 100644 --- a/racevisionGame/src/main/java/visualiser/model/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -1,4 +1,4 @@ -package visualiser.model; +package visualiser.layout; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; @@ -20,7 +20,7 @@ public class View3D extends Pane { /** * Observable list of renderable items */ - private ObservableList items; + private ObservableList items; /** * Rendering container for shapes */ @@ -89,13 +89,13 @@ public class View3D extends Pane { return camera; } - public void setItems(ObservableList items) { + public void setItems(ObservableList items) { this.items = items; - this.items.addListener((ListChangeListener) c -> { + this.items.addListener((ListChangeListener) 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); + for (Subject3D shape : c.getRemoved()) world.getChildren().remove(shape.getMesh()); + for (Subject3D shape : c.getAddedSubList()) world.getChildren().add(shape.getMesh()); } } }); @@ -113,10 +113,10 @@ public class View3D extends Pane { * 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()); + public void setPivot(Subject3D pivot) { + this.pivot.setX(pivot.getX()); + this.pivot.setY(pivot.getY()); + this.pivot.setZ(pivot.getZ()); } /** diff --git a/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java b/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java deleted file mode 100644 index 9314f5cd..00000000 --- a/racevisionGame/src/main/java/visualiser/model/BoatDisplay3D.java +++ /dev/null @@ -1,18 +0,0 @@ -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/VisualiserBoat.java b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java index 6cbfdaa3..555def15 100644 --- a/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java +++ b/racevisionGame/src/main/java/visualiser/model/VisualiserBoat.java @@ -1,11 +1,10 @@ package visualiser.model; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.scene.paint.Color; import network.Messages.Enums.BoatStatusEnum; -import shared.model.Azimuth; -import shared.model.Boat; -import shared.model.Constants; -import shared.model.GPSCoordinate; +import shared.model.*; import java.time.Duration; import java.time.ZonedDateTime; @@ -61,7 +60,8 @@ public class VisualiserBoat extends Boat { private boolean isClientBoat = false; - + private ObjectProperty positionProperty; + private ObjectProperty bearingProperty; /** @@ -239,4 +239,38 @@ public class VisualiserBoat extends Boat { public void setClientBoat(boolean clientBoat) { isClientBoat = clientBoat; } + + @Override + public GPSCoordinate getPosition() { + return positionProperty.get(); + } + + @Override + public void setPosition(GPSCoordinate position) { + if(this.positionProperty == null) { + this.positionProperty = new SimpleObjectProperty<>(); + } + this.positionProperty.set(position); + } + + public ObjectProperty positionProperty() { + return positionProperty; + } + + @Override + public Bearing getBearing() { + return bearingProperty.get(); + } + + @Override + public void setBearing(Bearing bearing) { + if(this.bearingProperty == null) { + this.bearingProperty = new SimpleObjectProperty<>(); + } + this.bearingProperty.set(bearing); + } + + public ObjectProperty bearingProperty() { + return bearingProperty; + } }