diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java index d1ef843e..381807b2 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java @@ -30,6 +30,7 @@ import javafx.scene.transform.Translate; import javafx.util.Callback; import network.Messages.Enums.RaceStatusEnum; import shared.dataInput.RaceDataSource; +import shared.enums.RoundingType; import shared.exceptions.BoatNotFoundException; import shared.model.*; import visualiser.app.App; @@ -70,6 +71,7 @@ public class RaceViewController extends Controller { private long positionTime = 0; private ResizableRaceCanvas raceCanvas; private boolean mapToggle = true; + private GPSConverter gpsConverter; /** * Arrow pointing to next mark in third person @@ -355,7 +357,7 @@ public class RaceViewController extends Controller { // Set up projection from GPS to view RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource(); - final GPSConverter gpsConverter = new GPSConverter(raceData, 450, 450); + gpsConverter = new GPSConverter(raceData, 450, 450); SkyBox skyBox = new SkyBox(750, 200, 250, 0, 210); viewSubjects.addAll(skyBox.getSkyBoxPlanes()); @@ -378,8 +380,9 @@ public class RaceViewController extends Controller { } // Position and add each mark to view for(Mark mark: race.getVisualiserRaceState().getMarks()) { - MeshView mesh = new MeshView(importerMark.getImport()); - Subject3D markModel = new Subject3D(mesh, mark.getSourceID()); +// MeshView mesh = new MeshView(importerMark.getImport()); +// Subject3D markModel = new Subject3D(mesh, mark.getSourceID()); + Subject3D markModel = new Subject3D(Assets3D.getMark(), mark.getSourceID()); markModel.setX(gpsConverter.convertGPS(mark.getPosition()).getX()); markModel.setZ(gpsConverter.convertGPS(mark.getPosition()).getY()); @@ -502,17 +505,33 @@ public class RaceViewController extends Controller { }; trackBoat.start(); - Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1)); - CompoundMark nextMark = boat.getCurrentLeg().getEndCompoundMark(); + //next mark indicator + //Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1)); + changeNextMark(boat.getCurrentLeg()); + viewSubjects.add(Assets3D.ccwNextArrow); + viewSubjects.add(Assets3D.cwNextArrow); + + AnimationTimer rotateArrows = new AnimationTimer() { + @Override + public void handle(long now) { + Assets3D.ccwNextArrow.setHeading(Assets3D.ccwNextArrow.getHeading().getAngle() - 3.0); + Assets3D.cwNextArrow.setHeading(Assets3D.cwNextArrow.getHeading().getAngle() + 3.0); + } + }; + rotateArrows.start(); + /*CompoundMark nextMark = boat.getCurrentLeg().getEndCompoundMark(); + view3D.getShape(nextMark.getMark1().getSourceID()).getMesh().setMaterial(markColor); if(nextMark.getMark2() != null) { view3D.getShape(nextMark.getMark2().getSourceID()).getMesh().setMaterial(markColor); - } + }*/ + Subject3D shockwave = new Shockwave(10); viewSubjects.add(shockwave); - boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr))); + //boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr))); + boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> changeNextMark(curr))); boat.hasCollidedProperty().addListener((o, prev, curr) -> Platform.runLater(() -> showCollision(boat, shockwave))); } // Fix initial bird's-eye position @@ -662,6 +681,57 @@ public class RaceViewController extends Controller { } } + private void changeNextMark(Leg leg){ + CompoundMark start = leg.getStartCompoundMark(); + CompoundMark end = leg.getEndCompoundMark(); + + //The last leg "finish" doesn't have compound marks. + if (start == null || end == null ) { + return; + } +/* + Leg legOfInterest; + for (int i = 0; i < raceState.getLegs().size(); i ++){ + if (raceState.getLegs().get(i) == leg){ + legOfInterest = raceState.getLegs().get(i); + break; + } + } + CompoundMark nextMark = leg.getStartCompoundMark(); + CompoundMark dirMark = leg.getEndCompoundMark();*/ + + boolean firstMarkCCW = end.getRoundingType() == RoundingType.Port; +// double angle = gpsConverter.getAngle(gpsConverter.convertGPS(dirMark.getMark1().getPosition()), +// gpsConverter.convertGPS(nextMark.getMark1().getPosition())); +// if (nextMark.getRoundingType() == RoundingType.Port){ +// if (angle < 90 || angle >= 270){ +// firstMarkCCW = false; +// } +// } else { +// if (angle < 270 && angle >= 90){ +// firstMarkCCW = false; +// } +// } + Mark startMark1 = end.getMark1(); + Mark startMark2 = end.getMark2(); + + if (firstMarkCCW){ + Assets3D.ccwNextArrow.setX(gpsConverter.convertGPS(startMark1.getPosition()).getX()); + Assets3D.ccwNextArrow.setZ(gpsConverter.convertGPS(startMark1.getPosition()).getY()); + if (end.getMark2() != null) { + Assets3D.cwNextArrow.setX(gpsConverter.convertGPS(startMark2.getPosition()).getX()); + Assets3D.cwNextArrow.setZ(gpsConverter.convertGPS(startMark2.getPosition()).getY()); + } + } else { + Assets3D.cwNextArrow.setX(gpsConverter.convertGPS(startMark1.getPosition()).getX()); + Assets3D.cwNextArrow.setZ(gpsConverter.convertGPS(startMark1.getPosition()).getY()); + if (end.getMark2() != null) { + Assets3D.ccwNextArrow.setX(gpsConverter.convertGPS(startMark2.getPosition()).getX()); + Assets3D.ccwNextArrow.setZ(gpsConverter.convertGPS(startMark2.getPosition()).getY()); + } + } + } + /** * Initialises the frame rate functionality. This allows for toggling the * frame rate, and connect the fps label to the race's fps property. diff --git a/racevisionGame/src/main/java/visualiser/layout/Assets3D.java b/racevisionGame/src/main/java/visualiser/layout/Assets3D.java index 756d5a9e..0c3b5aae 100644 --- a/racevisionGame/src/main/java/visualiser/layout/Assets3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/Assets3D.java @@ -1,9 +1,13 @@ package visualiser.layout; import com.interactivemesh.jfx.importer.obj.ObjModelImporter; +import com.interactivemesh.jfx.importer.stl.StlMeshImporter; import com.interactivemesh.jfx.importer.x3d.X3dModelImporter; import javafx.geometry.Point3D; import javafx.scene.Group; +import javafx.scene.paint.Color; +import javafx.scene.paint.Material; +import javafx.scene.paint.PhongMaterial; import javafx.scene.shape.MeshView; import javafx.scene.shape.Shape3D; import visualiser.Controllers.HostGameController; @@ -18,10 +22,33 @@ public class Assets3D { public static MeshView[] sails; public static Subject3D windArrow; public static Subject3D compass; + public static Subject3D cwNextArrow; + public static Subject3D ccwNextArrow; public static void loadAssets(){ loadSails(); loadWindArrow(); + loadNextArrow(); + } + + private static void loadNextArrow(){ + StlMeshImporter objModelImporter = new StlMeshImporter(); + String cwPath = "assets/Next Mark Arrow CW V1.0.stl"; + URL asset = Assets3D.class.getClassLoader().getResource(cwPath); + objModelImporter.read(asset); + Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1)); + + MeshView cwMesh = new MeshView(objModelImporter.getImport()); + cwMesh.setMaterial(markColor); + cwNextArrow = new Annotation3D(cwMesh); + + String ccwPath = "assets/Next Mark Arrow CCW V1.0.stl"; + URL ccwAsset = Assets3D.class.getClassLoader().getResource(ccwPath); + objModelImporter.read(ccwAsset); + + MeshView ccwMesh = new MeshView(objModelImporter.getImport()); + ccwMesh.setMaterial(markColor); + ccwNextArrow = new Annotation3D(ccwMesh); } private static void loadSails(){ @@ -45,6 +72,11 @@ public class Assets3D { return loadX3d(path); } + public static Shape3D getMark(){ + String path = "assets/Burger Bouy V1.1.x3d"; + return loadX3d(path); + } + private static void loadWindArrow(){ String compassPath = "assets/wind_compass.x3d"; compass = new Annotation3D(loadX3d(compassPath)); diff --git a/racevisionGame/src/main/resources/assets/Burger Bouy V1.1.x3d b/racevisionGame/src/main/resources/assets/Burger Bouy V1.1.x3d new file mode 100644 index 00000000..f377a490 --- /dev/null +++ b/racevisionGame/src/main/resources/assets/Burger Bouy V1.1.x3d @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/racevisionGame/src/main/resources/assets/Next Mark Arrow CCW V1.0.stl b/racevisionGame/src/main/resources/assets/Next Mark Arrow CCW V1.0.stl new file mode 100644 index 00000000..685e5340 Binary files /dev/null and b/racevisionGame/src/main/resources/assets/Next Mark Arrow CCW V1.0.stl differ diff --git a/racevisionGame/src/main/resources/assets/Next Mark Arrow CW V1.0.stl b/racevisionGame/src/main/resources/assets/Next Mark Arrow CW V1.0.stl new file mode 100644 index 00000000..d2469c12 Binary files /dev/null and b/racevisionGame/src/main/resources/assets/Next Mark Arrow CW V1.0.stl differ diff --git a/racevisionGame/src/main/resources/assets/textures/Burger Texture b/racevisionGame/src/main/resources/assets/textures/Burger Texture new file mode 100644 index 00000000..63cba3d3 Binary files /dev/null and b/racevisionGame/src/main/resources/assets/textures/Burger Texture differ