Merge branch 'tom' into nightmode

# Conflicts:
#	racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java
main
Joseph Gardner 8 years ago
commit 685b508f1e

@ -77,7 +77,7 @@ public class Event {
String boatsXMLFile = "mock/mockXML/boatTest.xml"; String boatsXMLFile = "mock/mockXML/boatTest.xml";
String regattaXMLFile = "mock/mockXML/regattaTest.xml"; String regattaXMLFile = "mock/mockXML/regattaTest.xml";
switch (mapIndex){ switch (mapIndex){
case 0:raceXMLFile = "mock/mockXML/raceSixPlayers.xml"; case 0:raceXMLFile = "mock/mockXML/ac35MapLayout.xml";
break; break;
case 1:raceXMLFile = "mock/mockXML/oMapLayout.xml"; case 1:raceXMLFile = "mock/mockXML/oMapLayout.xml";
break; break;
@ -90,13 +90,12 @@ public class Event {
boatsXMLFile = "mock/mockXML/boatTutorial.xml"; boatsXMLFile = "mock/mockXML/boatTutorial.xml";
regattaXMLFile = "mock/mockXML/regattaTutorial.xml"; regattaXMLFile = "mock/mockXML/regattaTutorial.xml";
break; break;
default: raceXMLFile = "mock/mockXML/raceSixPlayers.xml"; default: raceXMLFile = "mock/mockXML/ac35MapLayout.xml";
} }
if (singlePlayer) { if (singlePlayer) {
raceXMLFile = "mock/mockXML/raceSinglePlayer.xml";
boatsXMLFile = "mock/mockXML/boatsSinglePlayer.xml"; boatsXMLFile = "mock/mockXML/boatsSinglePlayer.xml";
} }

@ -109,8 +109,6 @@ public class MockRace extends RaceState {
colliderRegistry.addCollider(mark.getMark1()); colliderRegistry.addCollider(mark.getMark1());
if(mark.getMark2() != null) colliderRegistry.addCollider(mark.getMark2()); if(mark.getMark2() != null) colliderRegistry.addCollider(mark.getMark2());
} }
this.colliderRegistry.addAllColliders(boats);
} }
@ -133,9 +131,9 @@ public class MockRace extends RaceState {
this.boats.add(mockBoat); this.boats.add(mockBoat);
this.activeObserverCommands.put(boat.getSourceID(), new ActiveObserverCommand()); this.activeObserverCommands.put(boat.getSourceID(), new ActiveObserverCommand());
this.colliderRegistry.addCollider(mockBoat);
getRaceDataSource().incrementSequenceNumber(); getRaceDataSource().incrementSequenceNumber();
} }
/** /**

@ -28,7 +28,7 @@ public class Constants {
* Frame periods are multiplied by this to get the amount of time a single frame represents. * Frame periods are multiplied by this to get the amount of time a single frame represents.
* E.g., frame period = 20ms, scale = 5, frame represents 20 * 5 = 100ms, and so boats are simulated for 100ms, even though only 20ms actually occurred. * E.g., frame period = 20ms, scale = 5, frame represents 20 * 5 = 100ms, and so boats are simulated for 100ms, even though only 20ms actually occurred.
*/ */
public static final int RaceTimeScale = 2; public static final int RaceTimeScale = 1;
/** /**
* The race pre-start time, in milliseconds. 30 seconds. * The race pre-start time, in milliseconds. 30 seconds.

@ -17,8 +17,9 @@ public class MarkRoundingSequence {
/** /**
* For each leg, mark rounding information. * For each leg, mark rounding information.
* Maps between leg number and rounding data.
*/ */
private Map<Leg, MarkRoundingData> roundingPoints; private Map<Integer, MarkRoundingData> roundingPoints;
@ -34,7 +35,7 @@ public class MarkRoundingSequence {
* @return Rounding points for leg. * @return Rounding points for leg.
*/ */
public MarkRoundingData getRoundingData(Leg leg) { public MarkRoundingData getRoundingData(Leg leg) {
return roundingPoints.get(leg); return roundingPoints.get(leg.getLegNumber());
} }
@ -139,7 +140,7 @@ public class MarkRoundingSequence {
roundingData.setRoundCheck2Halfway(roundCheck2Halfway); roundingData.setRoundCheck2Halfway(roundCheck2Halfway);
this.roundingPoints.put(currentLeg, roundingData); this.roundingPoints.put(currentLeg.getLegNumber(), roundingData);
//Rounding points: //Rounding points:

@ -62,7 +62,7 @@ public class HostGameController extends Controller {
}); });
// set values and marks to be displayed // set values and marks to be displayed
sliderLength.setMin(2); sliderLength.setMin(5);
sliderLength.setMax(MAX_RACE_LENGTH); sliderLength.setMax(MAX_RACE_LENGTH);
sliderLength.setShowTickLabels(true); sliderLength.setShowTickLabels(true);
sliderLength.setMajorTickUnit(MAX_RACE_LENGTH-1); sliderLength.setMajorTickUnit(MAX_RACE_LENGTH-1);

@ -8,11 +8,14 @@ import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.scene.AmbientLight;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.PointLight;
import javafx.scene.control.Alert; import javafx.scene.control.Alert;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ButtonType; import javafx.scene.control.ButtonType;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.effect.Light;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
@ -145,15 +148,23 @@ public class InGameLobbyController extends Controller {
for (VisualiserBoat boat : copy) { for (VisualiserBoat boat : copy) {
View3D playerBoatToSet = new View3D(); View3D playerBoatToSet = new View3D();
playerBoatToSet.setItems(subjects); playerBoatToSet.setItems(subjects);
playerContainer.add(playerBoatToSet, (count % 3) , row); playerContainer.add(playerBoatToSet, (count % 3) , row);
playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10)); playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10));
SeaSurface sea = new SeaSurface(750, 200); // SeaSurface sea = new SeaSurface(750, 200);
sea.setX(250); // sea.setX(250);
sea.setZ(210); // sea.setZ(210);
subjects.add(sea); // subjects.add(sea);
//
NewSeaSurface sea = new NewSeaSurface();
Subject3D seaSubject = new Annotation3D(sea);
seaSubject.setX(50);
seaSubject.setZ(50);
seaSubject.setXRot(0);
subjects.add(seaSubject);
// MeshView mesh = new MeshView(importer.getImport()); // MeshView mesh = new MeshView(importer.getImport());
// Subject3D subject = new Subject3D(mesh,0); // Subject3D subject = new Subject3D(mesh,0);
@ -177,12 +188,14 @@ public class InGameLobbyController extends Controller {
if (boat.isClientBoat()) { if (boat.isClientBoat()) {
Shockwave boatHighlight = new Shockwave(10); /*Shockwave boatHighlight = new Shockwave(10);
boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1))); boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1)));*/
boatHighlight.setX(subject.getPosition().getX());
boatHighlight.setY(subject.getPosition().getY()); Assets3D.boatHighlight.setX(subject.getPosition().getX());
boatHighlight.setZ(subject.getPosition().getZ()); Assets3D.boatHighlight.setY(subject.getPosition().getY());
subjects.add(boatHighlight); Assets3D.boatHighlight.setZ(subject.getPosition().getZ());
subjects.add(Assets3D.boatHighlight);
subject.getMesh().toFront(); subject.getMesh().toFront();
} }
@ -326,6 +339,11 @@ public class InGameLobbyController extends Controller {
* Start button pressed. Currently only prints out start * Start button pressed. Currently only prints out start
*/ */
public void startBtnPressed(){ public void startBtnPressed(){
try {
HttpMatchBrowserHost.httpMatchBrowserHost.sendStarted();
} catch (IOException e) {
e.printStackTrace();
}
App.game.getRaceLogic().getRace().startRace(App.game.getRaceLogic().getRace().getRacePreparatoryTime(), true); App.game.getRaceLogic().getRace().startRace(App.game.getRaceLogic().getRace().getRacePreparatoryTime(), true);
} }

@ -29,11 +29,13 @@ import javafx.scene.shape.Cylinder;
import javafx.scene.paint.Stop; import javafx.scene.paint.Stop;
import javafx.scene.shape.MeshView; import javafx.scene.shape.MeshView;
import javafx.scene.shape.Shape3D; import javafx.scene.shape.Shape3D;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Translate; import javafx.scene.transform.Translate;
import javafx.util.Callback; import javafx.util.Callback;
import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.BoatStatusEnum;
import network.Messages.Enums.RaceStatusEnum; import network.Messages.Enums.RaceStatusEnum;
import shared.dataInput.RaceDataSource; import shared.dataInput.RaceDataSource;
import shared.enums.RoundingType;
import shared.exceptions.BoatNotFoundException; import shared.exceptions.BoatNotFoundException;
import shared.model.*; import shared.model.*;
import visualiser.app.App; import visualiser.app.App;
@ -88,6 +90,13 @@ public class RaceViewController extends Controller {
*/ */
private AnimationTimer pointToMark; private AnimationTimer pointToMark;
//seagulls
private ObservableList<Subject3D> seagulls = FXCollections.observableArrayList();
//seagulls goto
private Map<Subject3D, List<Double>> seagullsGoToX = new HashMap<>();
private Map<Subject3D, List<Double>> seagullsGoToY = new HashMap<>();
private double seagullSpeed = 0.01;
// note: it says it's not used but it is! do not remove :) // note: it says it's not used but it is! do not remove :)
private @FXML ArrowController arrowController; private @FXML ArrowController arrowController;
private @FXML NextMarkController nextMarkController; private @FXML NextMarkController nextMarkController;
@ -109,6 +118,7 @@ public class RaceViewController extends Controller {
private @FXML TableColumn<VisualiserBoat, Number> boatHealthColumn; private @FXML TableColumn<VisualiserBoat, Number> boatHealthColumn;
private @FXML LineChart<Number, Number> sparklineChart; private @FXML LineChart<Number, Number> sparklineChart;
private @FXML Label tutorialText; private @FXML Label tutorialText;
private @FXML ImageView tom;
private @FXML AnchorPane infoWrapper; private @FXML AnchorPane infoWrapper;
private @FXML AnchorPane lineChartWrapper; private @FXML AnchorPane lineChartWrapper;
private @FXML StackPane speedPane; private @FXML StackPane speedPane;
@ -148,6 +158,7 @@ public class RaceViewController extends Controller {
if (App.gameType == 4) { if (App.gameType == 4) {
isTutorial = true; isTutorial = true;
tutorialText.setVisible(true); tutorialText.setVisible(true);
tom.setVisible(true);
tutorialStates = new ArrayList<>(Arrays.asList(TutorialState.values())); tutorialStates = new ArrayList<>(Arrays.asList(TutorialState.values()));
currentState = tutorialStates.get(0); currentState = tutorialStates.get(0);
tutorialStates.remove(0); tutorialStates.remove(0);
@ -160,6 +171,7 @@ public class RaceViewController extends Controller {
} else { } else {
isTutorial = false; isTutorial = false;
tutorialText.setVisible(false); tutorialText.setVisible(false);
tom.setVisible(false);
} }
} }
@ -390,21 +402,39 @@ public class RaceViewController extends Controller {
RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource(); RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource();
gpsConverter = new GPSConverter(raceData, 450, 450); gpsConverter = new GPSConverter(raceData, 450, 450);
SkyBox skyBox = new SkyBox(750, 200, 250, 0, 210); SkyBox skyBox = Assets3D.skyBox;
viewSubjects.addAll(skyBox.getSkyBoxPlanes()); viewSubjects.addAll(skyBox.getSkyBoxPlanes());
// Set up sea surface // Set up sea surface
SeaSurface sea = new SeaSurface(750, 200); // SeaSurface sea = new SeaSurface(750, 200);
sea.setX(250); // sea.setX(250);
sea.setZ(210); // sea.setZ(210);
viewSubjects.add(sea); // viewSubjects.add(sea);
// Set up sea surface overlay // Set up sea surface overlay
SeaSurface seaOverlay = new SeaSurface(4000, 200); // SeaSurface seaOverlay = new SeaSurface(4000, 200);
seaOverlay.setX(250); // seaOverlay.setX(250);
seaOverlay.setZ(210); // seaOverlay.setZ(210);
viewSubjects.add(seaOverlay); // viewSubjects.add(seaOverlay);
// int seaX = 15;
// int seaY = 15;
int seaX = 15;
int seaY = 15;
for (int x = 0; x < seaX; x++) {
for (int y = 0; y < seaY; y++) {
NewSeaSurface seaSurface = new NewSeaSurface();
Subject3D seaSubject = new Annotation3D(seaSurface);
seaSubject.setXRot(0);
// seaSubject.setX(-75 + x * 50);
// seaSubject.setZ(-150 + y * 50);
// seaSubject.setX(-150 + x * 250);
// seaSubject.setZ(-80 + y * 250);
seaSubject.setX(-75 + x * 100);
seaSubject.setZ(-150 + y * 100);
seaSubject.setY(3);
viewSubjects.add(seaSubject);
}
}
Boundary3D boundary3D = new Boundary3D(visualiserRace.getVisualiserRaceState().getRaceDataSource().getBoundary(), gpsConverter); Boundary3D boundary3D = new Boundary3D(visualiserRace.getVisualiserRaceState().getRaceDataSource().getBoundary(), gpsConverter);
for (Subject3D subject3D: boundary3D.getBoundaryNodes()){ for (Subject3D subject3D: boundary3D.getBoundaryNodes()){
@ -412,8 +442,9 @@ public class RaceViewController extends Controller {
} }
// Position and add each mark to view // Position and add each mark to view
for(Mark mark: race.getVisualiserRaceState().getMarks()) { for(Mark mark: race.getVisualiserRaceState().getMarks()) {
MeshView mesh = new MeshView(importerMark.getImport()); // MeshView mesh = new MeshView(importerMark.getImport());
Subject3D markModel = new Subject3D(mesh, mark.getSourceID()); // Subject3D markModel = new Subject3D(mesh, mark.getSourceID());
Subject3D markModel = new Subject3D(Assets3D.getMark(), mark.getSourceID());
markModel.setX(gpsConverter.convertGPS(mark.getPosition()).getX()); markModel.setX(gpsConverter.convertGPS(mark.getPosition()).getX());
markModel.setZ(gpsConverter.convertGPS(mark.getPosition()).getY()); markModel.setZ(gpsConverter.convertGPS(mark.getPosition()).getY());
@ -432,14 +463,16 @@ public class RaceViewController extends Controller {
// Configure visualiser for client's boat // Configure visualiser for client's boat
if (boat.isClientBoat()) { if (boat.isClientBoat()) {
// Add player boat highlight // Add player boat highlight
Shockwave boatHighlight = new Shockwave(10); // Shockwave boatHighlight = new Shockwave(10);
boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1))); // boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1)));
viewSubjects.add(boatHighlight); // viewSubjects.add(boatHighlight);
viewSubjects.add(Assets3D.boatHighlight);
// Track player boat with camera // Track player boat with camera
viewSubjects.add(boatModel); viewSubjects.add(boatModel);
Platform.runLater(() -> { Platform.runLater(() -> {
view3D.trackSubject(boatModel); view3D.trackSubject(boatModel, 0);
view3D.setThirdPerson(); view3D.setThirdPerson();
}); });
@ -449,8 +482,8 @@ public class RaceViewController extends Controller {
public void handle(long now) { public void handle(long now) {
double boatX = gpsConverter.convertGPS(boat.getPosition()).getX(); double boatX = gpsConverter.convertGPS(boat.getPosition()).getX();
double boatZ = gpsConverter.convertGPS(boat.getPosition()).getY(); double boatZ = gpsConverter.convertGPS(boat.getPosition()).getY();
boatHighlight.setX(boatX); Assets3D.boatHighlight.setX(boatX);
boatHighlight.setZ(boatZ); Assets3D.boatHighlight.setZ(boatZ);
pointLight.setTranslateX(boatX); pointLight.setTranslateX(boatX);
pointLight.setTranslateZ(boatZ); pointLight.setTranslateZ(boatZ);
} }
@ -458,15 +491,22 @@ public class RaceViewController extends Controller {
highlightTrack.start(); highlightTrack.start();
// Highlight next mark only for player boat // Highlight next mark only for player boat
Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1)); // Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1));
CompoundMark nextMark = boat.getCurrentLeg().getEndCompoundMark(); // CompoundMark nextMark = boat.getCurrentLeg().getEndCompoundMark();
view3D.getShape(nextMark.getMark1().getSourceID()).getMesh().setMaterial(markColor); // view3D.getShape(nextMark.getMark1().getSourceID()).getMesh().setMaterial(markColor);
if(nextMark.getMark2() != null) { // if(nextMark.getMark2() != null) {
view3D.getShape(nextMark.getMark2().getSourceID()).getMesh().setMaterial(markColor); // view3D.getShape(nextMark.getMark2().getSourceID()).getMesh().setMaterial(markColor);
} // }
boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr))); // boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr)));
//next mark indicator
changeNextMark(boat.getCurrentLeg());
viewSubjects.add(Assets3D.ccwNextArrow);
viewSubjects.add(Assets3D.cwNextArrow);
boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> changeNextMark(curr)));
} else { } else {
viewSubjects.add(boatModel); viewSubjects.add(boatModel);
boatModel.getMesh().toFront();
} }
//Create health effect //Create health effect
@ -481,9 +521,31 @@ public class RaceViewController extends Controller {
sails3D.setMaterial(boatColorMat); sails3D.setMaterial(boatColorMat);
sailsSubject.setXRot(0d); sailsSubject.setXRot(0d);
sailsSubject.setHeading(visualiserRace.getVisualiserRaceState().getWindDirection().degrees()); sailsSubject.setHeading(visualiserRace.getVisualiserRaceState().getWindDirection().degrees());
viewSubjects.add(sailsSubject); viewSubjects.add(sailsSubject);
// SeagullFlock seagullFlock = new SeagullFlock(67, 43, 0);
//// seagullFlock.addToFlock();
//// seagullFlock.addToFlock();
// seagullFlock.setxBound(450);
// seagullFlock.setyBound(450);
// viewSubjects.addAll(seagullFlock.getSeagulls());
//
// Subject3D textSubject = new Annotation3D(new SeagullMesh());
// textSubject.setY(-10);
// viewSubjects.add(textSubject);
addToFlock();
seagullGoTo.start();
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();
AnimationTimer sailsFollowBoat = new AnimationTimer() { AnimationTimer sailsFollowBoat = new AnimationTimer() {
double sailCurrent = visualiserRace.getVisualiserRaceState().getWindDirection().degrees(); double sailCurrent = visualiserRace.getVisualiserRaceState().getWindDirection().degrees();
boolean canLuff = true; boolean canLuff = true;
@ -542,7 +604,7 @@ public class RaceViewController extends Controller {
} }
sailsSubject.setX(gpsConverter.convertGPS(boat.getPosition()).getX()); sailsSubject.setX(gpsConverter.convertGPS(boat.getPosition()).getX());
sailsSubject.setZ(gpsConverter.convertGPS(boat.getPosition()).getY()); sailsSubject.setZ(gpsConverter.convertGPS(boat.getPosition()).getY());
sailsSubject.getMesh().toFront();
} }
}; };
sailsFollowBoat.start(); sailsFollowBoat.start();
@ -566,9 +628,19 @@ public class RaceViewController extends Controller {
}; };
trackBoat.start(); trackBoat.start();
//next mark indicator
//Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1));
/*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); Subject3D shockwave = new Shockwave(10);
viewSubjects.add(shockwave); viewSubjects.add(shockwave);
//boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr)));
boat.hasCollidedProperty().addListener((o, prev, curr) -> Platform.runLater(() -> showCollision(boat, shockwave))); boat.hasCollidedProperty().addListener((o, prev, curr) -> Platform.runLater(() -> showCollision(boat, shockwave)));
} }
// Fix initial bird's-eye position // Fix initial bird's-eye position
@ -584,7 +656,12 @@ public class RaceViewController extends Controller {
// Bind zooming to scrolling // Bind zooming to scrolling
view3D.setOnScroll(e -> { view3D.setOnScroll(e -> {
view3D.updateDistance(e.getDeltaY()); //view3D.updateDistance(e.getDeltaY());
if (e.getDeltaY() > 0) {
view3D.zoomIn();
} else {
view3D.zoomOut();
}
}); });
// Bind zooming to keypress (Z/X default) // Bind zooming to keypress (Z/X default)
@ -681,11 +758,71 @@ public class RaceViewController extends Controller {
nextMarkController.show2d(); nextMarkController.show2d();
} }
/** private void setNextMarkArrowDirection(Mark mark1, Mark mark2, RoundingType roundingType, int direction){
* Swap the colour of the next mark to pass with the last mark passed boolean port = roundingType == RoundingType.Port;
* @param leg boat has started on Mark chosenMark = null;
*/
private void swapColours(Leg leg) { if (mark2 == null){
chosenMark = mark1;
} else {
boolean rounding = port;
switch (direction) {
case 2:
rounding = !port;
case 0:
if (rounding){
if (mark1.getPosition().getLongitude() < mark2.getPosition().getLongitude()){
chosenMark = mark1;
} else {
chosenMark = mark2;
}
} else {
if (mark1.getPosition().getLongitude() > mark2.getPosition().getLongitude()){
chosenMark = mark1;
} else {
chosenMark = mark2;
}
}
break;
case 3:
rounding = !port;
case 1:
if (rounding){
if (mark1.getPosition().getLatitude() > mark2.getPosition().getLatitude()){
chosenMark = mark1;
} else {
chosenMark = mark2;
}
} else {
if (mark1.getPosition().getLatitude() < mark2.getPosition().getLatitude()){
chosenMark = mark1;
} else {
chosenMark = mark2;
}
}
break;
}
}
if (chosenMark == null){
System.err.println("Mark to pick is null.");
return;
}
if (port){
Assets3D.ccwNextArrow.setX(gpsConverter.convertGPS(chosenMark.getPosition()).getX());
Assets3D.ccwNextArrow.setZ(gpsConverter.convertGPS(chosenMark.getPosition()).getY());
Assets3D.ccwNextArrow.getMesh().setVisible(true);
Assets3D.cwNextArrow.getMesh().setVisible(false);
} else {
Assets3D.cwNextArrow.setX(gpsConverter.convertGPS(chosenMark.getPosition()).getX());
Assets3D.cwNextArrow.setZ(gpsConverter.convertGPS(chosenMark.getPosition()).getY());
Assets3D.cwNextArrow.getMesh().setVisible(true);
Assets3D.ccwNextArrow.getMesh().setVisible(false);
}
}
private void changeNextMark(Leg leg){
CompoundMark start = leg.getStartCompoundMark(); CompoundMark start = leg.getStartCompoundMark();
CompoundMark end = leg.getEndCompoundMark(); CompoundMark end = leg.getEndCompoundMark();
@ -694,23 +831,28 @@ public class RaceViewController extends Controller {
return; return;
} }
Shape3D start1 = view3D.getShape(start.getMark1().getSourceID()).getMesh();
Shape3D end1 = view3D.getShape(end.getMark1().getSourceID()).getMesh();
Material nextMark = start1.getMaterial(); //find direction coming
Material lastMark = end1.getMaterial(); double angle = gpsConverter.getAngle(gpsConverter.convertGPS(start.getMark1().getPosition()),
gpsConverter.convertGPS(end.getMark1Position()));
start1.setMaterial(lastMark); angle = (Math.toDegrees(angle) % 360 + 360) % 360;
if(start.getMark2() != null) { int dir = 0; //0 = top 1 = right 2 = down 3 = down
Shape3D start2 = view3D.getShape(start.getMark2().getSourceID()).getMesh(); if (angle < 315){
start2.setMaterial(lastMark); if (angle > 45){
dir ++;
}
if (angle > 135){
dir ++;
}
if (angle > 225){
dir ++;
}
} }
end1.setMaterial(nextMark); Mark startMark1 = end.getMark1();
if(end.getMark2() != null) { Mark startMark2 = end.getMark2();
Shape3D end2 = view3D.getShape(end.getMark2().getSourceID()).getMesh();
end2.setMaterial(nextMark); setNextMarkArrowDirection(startMark1, startMark2, end.getRoundingType(), dir);
}
} }
/** /**
@ -924,14 +1066,18 @@ public class RaceViewController extends Controller {
if(boat.getHealth()<=0){ if(boat.getHealth()<=0){
//Boat is dead. Don't check it anymore for hp //Boat is dead. Don't check it anymore for hp
fp.displayDeath(fp.getSourceID()==raceState.getPlayerBoatID()); fp.displayDeath(fp.getSourceID()==raceState.getPlayerBoatID());
fp.setSourceID(0); Annotation3D sharks = new Annotation3D(Assets3D.getSharks());
try { sharks.setX(gpsConverter.convertGPS(boat.getPosition()).getX());
raceState.getBoat(boat.getSourceID()).setStatus(BoatStatusEnum.DNF); sharks.setZ(gpsConverter.convertGPS(boat.getPosition()).getY());
viewSubjects.add(sharks);
new AnimationTimer(){
@Override
public void handle(long now) {
sharks.setHeading(sharks.getHeading().getAngle() - 0.5);
}
}.start();
raceState.updateBoatPositions(raceState.getBoats()); fp.setSourceID(0);
} catch (BoatNotFoundException e) {
e.printStackTrace();
}
} }
else else
//Speed up tick when <=10 hp //Speed up tick when <=10 hp
@ -1118,4 +1264,85 @@ public class RaceViewController extends Controller {
deathPane.setVisible(false); deathPane.setVisible(false);
} }
private AnimationTimer seagullGoTo = new AnimationTimer() {
@Override
public void handle(long now) {
for (Subject3D seagull: seagulls) {
if (seagullsGoToX.get(seagull).size() > 0) {
//System.out.println(xPosition + " " + yPosition);
seagull.setHeading(GPSConverter.getAngle(new GraphCoordinate(seagull.getX(), seagull.getZ()),
new GraphCoordinate(seagullsGoToX.get(seagull).get(0), seagullsGoToY.get(seagull).get(0))));
double delx = seagullsGoToX.get(seagull).get(0) - seagull.getX();
double dely = seagullsGoToY.get(seagull).get(0) - seagull.getZ();
double scale = seagullSpeed / Math.sqrt(delx * delx + dely * dely);
if (scale < 1) {
seagull.setX(seagull.getX() + delx * scale);
seagull.setZ(seagull.getZ() + dely * scale);
} else {
seagullsGoToX.get(seagull).remove(0);
seagullsGoToY.get(seagull).remove(0);
}
} else {
randSeagullNewAction(seagull);
}
}
}
};
public void randSeagullNewAction(Subject3D seagull){
Random rand = new Random();
int nextAction = rand.nextInt(1);
switch(nextAction){
case 0:
//do a straight line
double nextX = rand.nextInt((int)gpsConverter.getLongitudeFactor());
/*if (nextX > this.xBound/2){
nextX = - nextX/2;
}*/
double nextY = rand.nextInt((int)gpsConverter.getLatitudeFactor());
/*if (nextY > this.yBound/2){
nextY = - nextY/2;
}*/
seagullsGoToX.get(seagull).add(nextX);
seagullsGoToY.get(seagull).add(nextY);
break;
case 1:
//do a octogan circle
seagullsGoToX.get(seagull).add(seagull.getX() - 3);
seagullsGoToX.get(seagull).add(seagull.getX() - 3);
seagullsGoToX.get(seagull).add(seagull.getX());
seagullsGoToX.get(seagull).add(seagull.getX() + 3);
seagullsGoToX.get(seagull).add(seagull.getX() + 6);
seagullsGoToX.get(seagull).add(seagull.getX() + 6);
seagullsGoToX.get(seagull).add(seagull.getX() + 3);
seagullsGoToX.get(seagull).add(seagull.getX());
//y
seagullsGoToY.get(seagull).add(seagull.getZ() - 3);
seagullsGoToY.get(seagull).add(seagull.getZ() - 6);
seagullsGoToY.get(seagull).add(seagull.getZ() - 9);
seagullsGoToY.get(seagull).add(seagull.getZ() - 9);
seagullsGoToY.get(seagull).add(seagull.getZ() - 6);
seagullsGoToY.get(seagull).add(seagull.getZ() - 3);
seagullsGoToY.get(seagull).add(seagull.getZ());
seagullsGoToY.get(seagull).add(seagull.getZ());
break;
}
}
public void addToFlock(){
Annotation3D newSeagull = new Annotation3D(new SeagullMesh());
newSeagull.setY(-15);
newSeagull.setX(67);
newSeagull.setZ(43);
newSeagull.setXRot(0);
seagulls.add(newSeagull);
seagullsGoToX.put(newSeagull, new ArrayList<>());
seagullsGoToY.put(newSeagull, new ArrayList<>());
viewSubjects.add(newSeagull);
randSeagullNewAction(newSeagull);
}
} }

@ -1,17 +1,31 @@
package visualiser.Controllers; 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.fxml.FXML;
import javafx.scene.control.Label; import javafx.scene.AmbientLight;
import javafx.scene.PointLight;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton; import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
import javafx.scene.media.AudioClip; import javafx.scene.media.AudioClip;
import javafx.scene.media.Media; import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer; import javafx.scene.media.MediaPlayer;
import javafx.scene.paint.Color;
import javafx.scene.shape.MeshView;
import javafx.stage.Modality; import javafx.stage.Modality;
import mock.exceptions.EventConstructionException; import mock.exceptions.EventConstructionException;
import visualiser.app.App; import visualiser.app.App;
import visualiser.layout.SeaSurface;
import visualiser.layout.SkyBox;
import visualiser.layout.Subject3D;
import visualiser.layout.View3D;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -30,9 +44,69 @@ import java.util.logging.Logger;
public class TitleController extends Controller { public class TitleController extends Controller {
private @FXML RadioButton dayModeRD; private @FXML RadioButton dayModeRD;
private @FXML RadioButton nightModeRD; private @FXML RadioButton nightModeRD;
private @FXML Label tutorialLabel; private @FXML Button tutorialButton;
private @FXML Pane menuPane;
private @FXML ImageView imgSun; private @FXML ImageView imgSun;
private @FXML GridPane view3DContainer;
private ToggleGroup toggleGroup = new ToggleGroup();
public void initialize() {
dayModeRD.setToggleGroup(toggleGroup);
nightModeRD.setToggleGroup(toggleGroup);
AmbientLight ambientLight = new AmbientLight(Color.web("#CCCCFF"));
ambientLight.setTranslateX(250);
ambientLight.setTranslateZ(210);
ambientLight.setLightOn(true);
PointLight pointLight = new PointLight(Color.web("#AAAAFF"));
pointLight.setTranslateX(250);
pointLight.setTranslateZ(210);
pointLight.setLightOn(true);
ObservableList<Subject3D> subjects = FXCollections.observableArrayList();
View3D view3D = new View3D();
view3D.addAmbientLight(ambientLight);
view3D.addPointLight(pointLight);
view3D.setDistance(10);
view3D.setPitch(5);
view3D.setItems(subjects);
SkyBox skyBox = new SkyBox(750,200,250,0,250);
subjects.addAll(skyBox.getSkyBoxPlanes());
SeaSurface seaSurface = new SeaSurface(750, 200);
seaSurface.setX(250);
seaSurface.setZ(250);
subjects.add(seaSurface);
URL asset = RaceViewController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl");
StlMeshImporter importer = new StlMeshImporter();
importer.read(asset);
Subject3D boat = new Subject3D(new MeshView(importer.getImport()), 0);
double radius = 100;
boat.setX(0);
boat.setZ(radius);
boat.setScale(0.1);
subjects.add(boat);
view3D.trackSubject(boat, -45);
view3DContainer.add(view3D, 0, 0);
AnimationTimer loop = new AnimationTimer() {
double angle = -90;
double offset = 0.05;
@Override
public void handle(long now) {
boat.setX(radius * Math.cos(angle * Math.PI/180));
boat.setZ(radius * Math.sin(angle * Math.PI/180));
boat.setHeading(-angle);
angle += offset;
}
};
loop.start();
}
/** /**
* Method called when the 'host a game' button is pressed. * Method called when the 'host a game' button is pressed.
@ -58,10 +132,7 @@ public class TitleController extends Controller {
*/ */
public void setDayMode(){ public void setDayMode(){
dayModeRD.getScene().getStylesheets().clear(); dayModeRD.getScene().getStylesheets().clear();
menuPane.getStylesheets().clear();
imgSun.setImage(new Image(getClass().getResource("/visualiser/images/sun.png").toExternalForm()));
dayModeRD.getScene().getStylesheets().add("/css/dayMode.css"); dayModeRD.getScene().getStylesheets().add("/css/dayMode.css");
menuPane.setStyle("-fx-background-color: #6be6ff;");
nightModeRD.setSelected(false); nightModeRD.setSelected(false);
App.dayMode = true; App.dayMode = true;
} }
@ -71,10 +142,7 @@ public class TitleController extends Controller {
*/ */
public void setNightMode(){ public void setNightMode(){
nightModeRD.getScene().getStylesheets().clear(); nightModeRD.getScene().getStylesheets().clear();
menuPane.getStylesheets().clear();
imgSun.setImage(new Image(getClass().getResource("/visualiser/images/sunsleep.png").toExternalForm()));
nightModeRD.getScene().getStylesheets().add("/css/nightMode.css"); nightModeRD.getScene().getStylesheets().add("/css/nightMode.css");
menuPane.setStyle("-fx-background-color: #1f2c60;");
dayModeRD.setSelected(false); dayModeRD.setSelected(false);
App.dayMode = false; App.dayMode = false;
} }

@ -134,7 +134,6 @@ public class App extends Application {
FXMLLoader loader = new FXMLLoader(getClass().getResource FXMLLoader loader = new FXMLLoader(getClass().getResource
("/visualiser/scenes/title.fxml")); ("/visualiser/scenes/title.fxml"));
Parent root = loader.load(); Parent root = loader.load();
stage.setResizable(false);
Scene scene = new Scene(root); Scene scene = new Scene(root);
stage.setTitle("The Boat Game - Burgers & Boats"); stage.setTitle("The Boat Game - Burgers & Boats");
stage.getIcons().add(new Image(getClass().getClassLoader().getResourceAsStream("images/SailIcon.png"))); stage.getIcons().add(new Image(getClass().getClassLoader().getResourceAsStream("images/SailIcon.png")));

@ -1,9 +1,13 @@
package visualiser.layout; package visualiser.layout;
import com.interactivemesh.jfx.importer.obj.ObjModelImporter; import com.interactivemesh.jfx.importer.obj.ObjModelImporter;
import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import com.interactivemesh.jfx.importer.x3d.X3dModelImporter; import com.interactivemesh.jfx.importer.x3d.X3dModelImporter;
import javafx.geometry.Point3D; import javafx.geometry.Point3D;
import javafx.scene.Group; 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.MeshView;
import javafx.scene.shape.Shape3D; import javafx.scene.shape.Shape3D;
import visualiser.Controllers.HostGameController; import visualiser.Controllers.HostGameController;
@ -16,12 +20,66 @@ import java.net.URL;
public class Assets3D { public class Assets3D {
public static MeshView[] sails; public static MeshView[] sails;
public static MeshView[] sea;
public static MeshView[] seagull;
public static Subject3D windArrow; public static Subject3D windArrow;
public static Subject3D compass; public static Subject3D compass;
public static Subject3D cwNextArrow;
public static Subject3D ccwNextArrow;
public static SkyBox skyBox;
public static Subject3D boatHighlight;
public static Subject3D sharks;
public static void loadAssets(){ public static void loadAssets(){
loadSails(); loadSails();
loadWindArrow(); loadWindArrow();
loadNextArrow();
loadSeaSurface();
loadSkybox();
loadSeagull();
loadBoatHightlight();
}
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);
cwMesh.setMouseTransparent(true);
cwMesh.toBack();
cwMesh.setVisible(false);
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);
ccwMesh.setMouseTransparent(true);
ccwMesh.toBack();
cwMesh.setVisible(false);
ccwNextArrow = new Annotation3D(ccwMesh);
}
private static void loadBoatHightlight(){
Material markColor = new PhongMaterial(new Color(0,1,0,0.5));
StlMeshImporter objModelImporter = new StlMeshImporter();
String path = "assets/V1.0 Boat Highlight.stl";
URL highlight = Assets3D.class.getClassLoader().getResource(path);
objModelImporter.read(highlight);
MeshView hMesh = new MeshView(objModelImporter.getImport());
hMesh.setMaterial(markColor);
hMesh.setMouseTransparent(true);
hMesh.toBack();
boatHighlight = new Subject3D(hMesh, 0);
} }
private static void loadSails(){ private static void loadSails(){
@ -40,11 +98,46 @@ public class Assets3D {
} }
} }
private static void loadSeaSurface(){
sea = new MeshView[100];
ObjModelImporter objModelImporter = new ObjModelImporter();
for (int i = 0; i < sea.length; i++){
// String path = String.format("assets/Ocean V1.0 Small Animation/Ocean V1.0 Large Animation_%06d.obj", i + 1);
// String path = String.format("assets/Ocean V1.0 Animation/Ocean V1.0_%06d.obj", i + 1);
String path = String.format("assets/Ocean Animation/Ocean Animation_%06d.obj", i + 1);
URL asset = Assets3D.class.getClassLoader().getResource(path);
objModelImporter.read(asset);
if (objModelImporter.getImport().length > 0) {
sea[i] = objModelImporter.getImport()[0];
}
}
}
private static void loadSeagull(){
seagull = new MeshView[30];
ObjModelImporter objModelImporter = new ObjModelImporter();
for (int i = 0; i < seagull.length; i++){
String path = String.format("assets/V1.1 Animated/Seagull V1.1_%06d.obj", i + 1);
URL asset = Assets3D.class.getClassLoader().getResource(path);
objModelImporter.read(asset);
if (objModelImporter.getImport().length > 0) {
seagull[i] = objModelImporter.getImport()[0];
}
}
}
public static Shape3D getBoat(){ public static Shape3D getBoat(){
String path = "assets/V1.4 Boat.x3d"; String path = "assets/V1.4 Boat.x3d";
return loadX3d(path); return loadX3d(path);
} }
public static Shape3D getMark(){
String path = "assets/Burger Bouy V1.1.x3d";
return loadX3d(path);
}
private static void loadWindArrow(){ private static void loadWindArrow(){
String compassPath = "assets/wind_compass.x3d"; String compassPath = "assets/wind_compass.x3d";
compass = new Annotation3D(loadX3d(compassPath)); compass = new Annotation3D(loadX3d(compassPath));
@ -52,6 +145,11 @@ public class Assets3D {
windArrow = new Annotation3D(loadX3d(arrowPath)); windArrow = new Annotation3D(loadX3d(arrowPath));
} }
public static Shape3D getSharks(){
String path = "assets/V1.0 Sharks.x3d";
return loadX3d(path);
}
public static Shape3D loadX3d(String path){ public static Shape3D loadX3d(String path){
X3dModelImporter x3dModelImporter = new X3dModelImporter(); X3dModelImporter x3dModelImporter = new X3dModelImporter();
URL asset = Assets3D.class.getClassLoader().getResource(path); URL asset = Assets3D.class.getClassLoader().getResource(path);
@ -68,4 +166,8 @@ public class Assets3D {
return null; return null;
} }
private static void loadSkybox(){
skyBox = new SkyBox(750, 200, 250, 0, 210);
}
} }

@ -0,0 +1,31 @@
package visualiser.layout;
import javafx.animation.AnimationTimer;
import javafx.scene.paint.Color;
import javafx.scene.paint.Material;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.MeshView;
/**
* Created by Gondr on 27/09/2017.
*/
public class NewSeaSurface extends MeshView{
private int seaIndex = 0;
private AnimationTimer seaRipple = new AnimationTimer() {
@Override
public void handle(long now) {
seaIndex = (seaIndex + 1) % Assets3D.sea.length;
setMesh(Assets3D.sea[seaIndex].getMesh());
}
};
public NewSeaSurface(){
super(Assets3D.sea[0].getMesh());
Color seaBlue = new Color(0.284, 0.573, 1.00, 1);
Material seaMat = new PhongMaterial(seaBlue);
setMaterial(seaMat);
setMouseTransparent(true);
seaRipple.start();
}
}

@ -1,5 +1,6 @@
package visualiser.layout; package visualiser.layout;
import javafx.animation.AnimationTimer;
import javafx.geometry.Point3D; import javafx.geometry.Point3D;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
@ -16,7 +17,7 @@ import visualiser.utils.PerlinNoiseGenerator;
/** /**
* Creates a SeaSurface * Creates a SeaSurface
*/ */
public class SeaSurface extends Subject3D { public class SeaSurface extends Annotation3D {
private static Image image; private static Image image;
/** /**
@ -26,7 +27,7 @@ public class SeaSurface extends Subject3D {
* @param freq frequency the perlin noise is to be generated at * @param freq frequency the perlin noise is to be generated at
*/ */
public SeaSurface(int size, double freq) { public SeaSurface(int size, double freq) {
super(createSurface(size, freq), 0); super(createSurface(size, freq));
image = new Image(getClass().getClassLoader().getResourceAsStream("images/skybox/ThickCloudsWaterDown2048.png")); image = new Image(getClass().getClassLoader().getResourceAsStream("images/skybox/ThickCloudsWaterDown2048.png"));
} }

@ -0,0 +1,144 @@
package visualiser.layout;
import javafx.animation.AnimationTimer;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.transform.Translate;
import visualiser.model.GraphCoordinate;
import visualiser.utils.GPSConverter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by Gondr on 28/09/2017.
*/
public class SeagullFlock{
private ObservableList<Subject3D> seagulls = FXCollections.observableArrayList();
private double xPos = 0;
private double yPos = 0;
private double zPos = 20;
private double heading = 0;
private double[] xOffset = {0, -5, -5};
private double[] yOffset = {0, -5, 5};
private double xBound = Integer.MAX_VALUE;//-/+
private double yBound = Integer.MAX_VALUE;
private List<Double> goToX = new ArrayList<>();
private List<Double> goToY = new ArrayList<>();
private double speed = 0.01;
private AnimationTimer goTo = new AnimationTimer() {
@Override
public void handle(long now) {
if (goToX.size() > 0) {
//System.out.println(xPosition + " " + yPosition);
heading = GPSConverter.getAngle(new GraphCoordinate(xPos, yPos),
new GraphCoordinate(goToX.get(0), goToY.get(0)));
double delx = goToX.get(0) - xPos;
double dely = goToY.get(0) - yPos;
double scale = speed / Math.sqrt(delx * delx + dely * dely);
if (scale < 1) {
xPos += delx * scale;
yPos += dely * scale;
} else {
goToX.remove(0);
goToY.remove(0);
}
}else {
stop();
randNewAction();
}
}
};
private AnimationTimer update = new AnimationTimer() {
@Override
public void handle(long now) {
for (int i = 0; i < seagulls.size(); i++){
Subject3D seagull = seagulls.get(i);
seagull.getMesh().setTranslateY(zPos);
seagull.setHeading(heading);
seagull.setX(xPos + xOffset[i]);
seagull.setZ(yPos + yOffset[i]);
}
}
};
public SeagullFlock() {
this(0d, 0d, 0d);
}
public SeagullFlock(double x, double y, double z){
xPos = x;
yPos = y;
zPos = z;
addToFlock();
update.start();
randNewAction();
}
public void addToFlock(){
if (seagulls.size() < 3) {
Annotation3D newSeagull = new Annotation3D(new SeagullMesh());
newSeagull.setXRot(0);
seagulls.add(newSeagull);
// seagulls.add(new Annotation3D(new Sphere(5)));
}
}
public void setxBound(double xBound) {
this.xBound = xBound;
}
public void setyBound(double yBound) {
this.yBound = yBound;
}
public void randNewAction(){
Random rand = new Random();
int nextAction = rand.nextInt(1);
switch(nextAction){
case 0:
//do a straight line
double nextX = rand.nextInt((int)this.xBound);
/*if (nextX > this.xBound/2){
nextX = - nextX/2;
}*/
double nextY = rand.nextInt((int)this.yBound);
/*if (nextY > this.yBound/2){
nextY = - nextY/2;
}*/
goToX.add(nextX);
goToY.add(nextY);
break;
case 1:
//do a octogan circle
goToX.add(xPos - 3);
goToX.add(xPos - 3);
goToX.add(xPos);
goToX.add(xPos + 3);
goToX.add(xPos + 6);
goToX.add(xPos + 6);
goToX.add(xPos + 3);
goToX.add(xPos);
//y
goToX.add(yPos - 3);
goToX.add(yPos - 6);
goToX.add(yPos - 9);
goToX.add(yPos - 9);
goToX.add(yPos - 6);
goToX.add(yPos - 3);
goToX.add(yPos);
goToX.add(yPos);
break;
}
goTo.start();
}
public List<Subject3D> getSeagulls() {
return seagulls;
}
}

@ -0,0 +1,60 @@
package visualiser.layout;
import javafx.animation.AnimationTimer;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.MeshView;
import java.util.Random;
/**
* Created by Gondr on 28/09/2017.
*/
public class SeagullMesh extends MeshView{
private int index = 0;
private int isFlapping = 0;
private int flapPeriod;
private int flapStrength;
private int periodElapsed = 0;
public SeagullMesh() {
setMesh(Assets3D.seagull[0].getMesh());
PhongMaterial white = new PhongMaterial(Color.WHITE);
setMaterial(white);
Random rand = new Random();
flapPeriod = rand.nextInt(9);
flapPeriod = 60 * (11 + flapPeriod);
flapStrength = rand.nextInt(3) + 2;
scheduledFlap.start();
}
private AnimationTimer flap = new AnimationTimer() {
@Override
public void handle(long now) {
index = (index + 1) % Assets3D.seagull.length;
setMesh(Assets3D.seagull[index].getMesh());
if (index == 0){
isFlapping ++;
if (isFlapping >= flapStrength){
stop();
setMesh(Assets3D.seagull[0].getMesh());
isFlapping = 0;
}
}
}
};
private AnimationTimer scheduledFlap = new AnimationTimer() {
@Override
public void handle(long now) {
if (periodElapsed == 0 && isFlapping == 0){
startFlapping();
}
periodElapsed = (periodElapsed + 1) % flapPeriod;
}
};
public void startFlapping(){
flap.start();
}
}

@ -174,7 +174,7 @@ public class View3D extends Pane {
PickResult result = e.getPickResult(); PickResult result = e.getPickResult();
if(result != null && result.getIntersectedNode() != null && result.getIntersectedNode() instanceof Shape3D) { if(result != null && result.getIntersectedNode() != null && result.getIntersectedNode() instanceof Shape3D) {
untrackSubject(); untrackSubject();
trackSubject(shapeMap.get(result.getIntersectedNode())); trackSubject(shapeMap.get(result.getIntersectedNode()), 0);
setThirdPerson(); setThirdPerson();
} }
}); });
@ -215,15 +215,16 @@ public class View3D extends Pane {
/** /**
* Set camera to follow the selected subject * Set camera to follow the selected subject
* @param subject to track * @param subject to track
* @param yaw to add to boat heading
*/ */
public void trackSubject(Subject3D subject) { public void trackSubject(Subject3D subject, double yaw) {
target.set(subject); target.set(subject);
this.trackBoat = new AnimationTimer() { this.trackBoat = new AnimationTimer() {
@Override @Override
public void handle(long now) { public void handle(long now) {
updatePivot(target.get().getPosition()); updatePivot(target.get().getPosition());
setYaw(target.get().getHeading().getAngle()); setYaw(target.get().getHeading().getAngle() + yaw);
} }
}; };
trackBoat.start(); trackBoat.start();
@ -268,8 +269,10 @@ public class View3D extends Pane {
public void updateDistance(double delta) { public void updateDistance(double delta) {
double newDistance = -this.distance.getZ() + delta; double newDistance = -this.distance.getZ() + delta;
if (target.get() == null){ if (target.get() == null){
if (newDistance > MAX_ZOOM_LIMIT){ if (newDistance > MAX_ZOOM_LIMIT) {
setDistance(MAX_ZOOM_LIMIT); setDistance(MAX_ZOOM_LIMIT);
} else if (newDistance <= ZOOM_IN_LIMIT) {
setDistance(ZOOM_IN_LIMIT);
} else { } else {
setDistance(newDistance); setDistance(newDistance);
} }

@ -96,6 +96,10 @@ public class HttpMatchBrowserHost extends Thread {
} }
} }
public void sendStarted() throws IOException {
sendHttp("http://api.umbrasheep.com/seng/match_started/");
}
/** /**
* THe host starts sending out heartbeat messages every 2 seconds. * THe host starts sending out heartbeat messages every 2 seconds.
*/ */

@ -111,4 +111,11 @@ public class GPSConverter {
return Math.atan2(coord2.getX() - coord1.getX(), coord2.getY() - coord1.getY()); return Math.atan2(coord2.getX() - coord1.getX(), coord2.getY() - coord1.getY());
} }
public double getLongitudeFactor() {
return longitudeFactor;
}
public double getLatitudeFactor() {
return latitudeFactor;
}
} }

File diff suppressed because one or more lines are too long

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

@ -0,0 +1,12 @@
# Blender MTL File: 'Ocean V1.0.blend'
# Material Count: 1
newmtl Material
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 2

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save