Merge branch 'master' into tom
This commit is contained in:
@@ -62,7 +62,7 @@ public class HostGameController extends Controller {
|
||||
});
|
||||
|
||||
// set values and marks to be displayed
|
||||
sliderLength.setMin(2);
|
||||
sliderLength.setMin(5);
|
||||
sliderLength.setMax(MAX_RACE_LENGTH);
|
||||
sliderLength.setShowTickLabels(true);
|
||||
sliderLength.setMajorTickUnit(MAX_RACE_LENGTH-1);
|
||||
|
||||
@@ -8,11 +8,14 @@ import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.AmbientLight;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.PointLight;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.effect.Light;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
@@ -145,15 +148,23 @@ public class InGameLobbyController extends Controller {
|
||||
|
||||
for (VisualiserBoat boat : copy) {
|
||||
View3D playerBoatToSet = new View3D();
|
||||
|
||||
playerBoatToSet.setItems(subjects);
|
||||
|
||||
playerContainer.add(playerBoatToSet, (count % 3) , row);
|
||||
playerContainer.setMargin(playerBoatToSet, new Insets(10, 10, 10, 10));
|
||||
|
||||
SeaSurface sea = new SeaSurface(750, 200);
|
||||
sea.setX(250);
|
||||
sea.setZ(210);
|
||||
subjects.add(sea);
|
||||
// SeaSurface sea = new SeaSurface(750, 200);
|
||||
// sea.setX(250);
|
||||
// sea.setZ(210);
|
||||
// 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());
|
||||
// Subject3D subject = new Subject3D(mesh,0);
|
||||
@@ -177,12 +188,14 @@ public class InGameLobbyController extends Controller {
|
||||
|
||||
|
||||
if (boat.isClientBoat()) {
|
||||
Shockwave boatHighlight = new Shockwave(10);
|
||||
boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1)));
|
||||
boatHighlight.setX(subject.getPosition().getX());
|
||||
boatHighlight.setY(subject.getPosition().getY());
|
||||
boatHighlight.setZ(subject.getPosition().getZ());
|
||||
subjects.add(boatHighlight);
|
||||
/*Shockwave boatHighlight = new Shockwave(10);
|
||||
boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1)));*/
|
||||
|
||||
Assets3D.boatHighlight.setX(subject.getPosition().getX());
|
||||
Assets3D.boatHighlight.setY(subject.getPosition().getY());
|
||||
Assets3D.boatHighlight.setZ(subject.getPosition().getZ());
|
||||
|
||||
subjects.add(Assets3D.boatHighlight);
|
||||
subject.getMesh().toFront();
|
||||
}
|
||||
|
||||
@@ -326,6 +339,11 @@ public class InGameLobbyController extends Controller {
|
||||
* Start button pressed. Currently only prints out start
|
||||
*/
|
||||
public void startBtnPressed(){
|
||||
try {
|
||||
HttpMatchBrowserHost.httpMatchBrowserHost.sendStarted();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
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.shape.MeshView;
|
||||
import javafx.scene.shape.Shape3D;
|
||||
import javafx.scene.shape.Sphere;
|
||||
import javafx.scene.transform.Translate;
|
||||
import javafx.util.Callback;
|
||||
import network.Messages.Enums.BoatStatusEnum;
|
||||
import network.Messages.Enums.RaceStatusEnum;
|
||||
import shared.dataInput.RaceDataSource;
|
||||
import shared.enums.RoundingType;
|
||||
import shared.exceptions.BoatNotFoundException;
|
||||
import shared.model.*;
|
||||
import visualiser.app.App;
|
||||
@@ -88,6 +90,13 @@ public class RaceViewController extends Controller {
|
||||
*/
|
||||
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 :)
|
||||
private @FXML ArrowController arrowController;
|
||||
private @FXML NextMarkController nextMarkController;
|
||||
@@ -388,20 +397,39 @@ public class RaceViewController extends Controller {
|
||||
RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource();
|
||||
gpsConverter = new GPSConverter(raceData, 450, 450);
|
||||
|
||||
SkyBox skyBox = new SkyBox(750, 200, 250, 0, 210);
|
||||
SkyBox skyBox = Assets3D.skyBox;
|
||||
viewSubjects.addAll(skyBox.getSkyBoxPlanes());
|
||||
|
||||
// Set up sea surface
|
||||
SeaSurface sea = new SeaSurface(750, 200);
|
||||
sea.setX(250);
|
||||
sea.setZ(210);
|
||||
viewSubjects.add(sea);
|
||||
// SeaSurface sea = new SeaSurface(750, 200);
|
||||
// sea.setX(250);
|
||||
// sea.setZ(210);
|
||||
// viewSubjects.add(sea);
|
||||
|
||||
// Set up sea surface overlay
|
||||
SeaSurface seaOverlay = new SeaSurface(4000, 200);
|
||||
seaOverlay.setX(250);
|
||||
seaOverlay.setZ(210);
|
||||
viewSubjects.add(seaOverlay);
|
||||
// SeaSurface seaOverlay = new SeaSurface(4000, 200);
|
||||
// seaOverlay.setX(250);
|
||||
// seaOverlay.setZ(210);
|
||||
// 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);
|
||||
for (Subject3D subject3D: boundary3D.getBoundaryNodes()){
|
||||
@@ -409,8 +437,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());
|
||||
@@ -429,9 +458,11 @@ public class RaceViewController extends Controller {
|
||||
// Configure visualiser for client's boat
|
||||
if (boat.isClientBoat()) {
|
||||
// Add player boat highlight
|
||||
Shockwave boatHighlight = new Shockwave(10);
|
||||
boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1)));
|
||||
viewSubjects.add(boatHighlight);
|
||||
// Shockwave boatHighlight = new Shockwave(10);
|
||||
// boatHighlight.getMesh().setMaterial(new PhongMaterial(new Color(1, 1, 0, 0.1)));
|
||||
// viewSubjects.add(boatHighlight);
|
||||
|
||||
viewSubjects.add(Assets3D.boatHighlight);
|
||||
|
||||
// Track player boat with camera
|
||||
viewSubjects.add(boatModel);
|
||||
@@ -444,22 +475,29 @@ public class RaceViewController extends Controller {
|
||||
AnimationTimer highlightTrack = new AnimationTimer() {
|
||||
@Override
|
||||
public void handle(long now) {
|
||||
boatHighlight.setX(gpsConverter.convertGPS(boat.getPosition()).getX());
|
||||
boatHighlight.setZ(gpsConverter.convertGPS(boat.getPosition()).getY());
|
||||
Assets3D.boatHighlight.setX(gpsConverter.convertGPS(boat.getPosition()).getX());
|
||||
Assets3D.boatHighlight.setZ(gpsConverter.convertGPS(boat.getPosition()).getY());
|
||||
}
|
||||
};
|
||||
highlightTrack.start();
|
||||
|
||||
// Highlight next mark only for player boat
|
||||
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);
|
||||
}
|
||||
boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr)));
|
||||
// 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);
|
||||
// }
|
||||
// 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 {
|
||||
viewSubjects.add(boatModel);
|
||||
boatModel.getMesh().toFront();
|
||||
}
|
||||
|
||||
//Create health effect
|
||||
@@ -474,9 +512,31 @@ public class RaceViewController extends Controller {
|
||||
sails3D.setMaterial(boatColorMat);
|
||||
sailsSubject.setXRot(0d);
|
||||
sailsSubject.setHeading(visualiserRace.getVisualiserRaceState().getWindDirection().degrees());
|
||||
|
||||
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() {
|
||||
double sailCurrent = visualiserRace.getVisualiserRaceState().getWindDirection().degrees();
|
||||
boolean canLuff = true;
|
||||
@@ -535,7 +595,7 @@ public class RaceViewController extends Controller {
|
||||
}
|
||||
sailsSubject.setX(gpsConverter.convertGPS(boat.getPosition()).getX());
|
||||
sailsSubject.setZ(gpsConverter.convertGPS(boat.getPosition()).getY());
|
||||
|
||||
sailsSubject.getMesh().toFront();
|
||||
}
|
||||
};
|
||||
sailsFollowBoat.start();
|
||||
@@ -559,9 +619,19 @@ public class RaceViewController extends Controller {
|
||||
};
|
||||
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);
|
||||
viewSubjects.add(shockwave);
|
||||
|
||||
//boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr)));
|
||||
boat.hasCollidedProperty().addListener((o, prev, curr) -> Platform.runLater(() -> showCollision(boat, shockwave)));
|
||||
}
|
||||
// Fix initial bird's-eye position
|
||||
@@ -679,11 +749,71 @@ public class RaceViewController extends Controller {
|
||||
nextMarkController.show2d();
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the colour of the next mark to pass with the last mark passed
|
||||
* @param leg boat has started on
|
||||
*/
|
||||
private void swapColours(Leg leg) {
|
||||
private void setNextMarkArrowDirection(Mark mark1, Mark mark2, RoundingType roundingType, int direction){
|
||||
boolean port = roundingType == RoundingType.Port;
|
||||
Mark chosenMark = null;
|
||||
|
||||
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 end = leg.getEndCompoundMark();
|
||||
|
||||
@@ -692,23 +822,28 @@ public class RaceViewController extends Controller {
|
||||
return;
|
||||
}
|
||||
|
||||
Shape3D start1 = view3D.getShape(start.getMark1().getSourceID()).getMesh();
|
||||
Shape3D end1 = view3D.getShape(end.getMark1().getSourceID()).getMesh();
|
||||
|
||||
Material nextMark = start1.getMaterial();
|
||||
Material lastMark = end1.getMaterial();
|
||||
|
||||
start1.setMaterial(lastMark);
|
||||
if(start.getMark2() != null) {
|
||||
Shape3D start2 = view3D.getShape(start.getMark2().getSourceID()).getMesh();
|
||||
start2.setMaterial(lastMark);
|
||||
//find direction coming
|
||||
double angle = gpsConverter.getAngle(gpsConverter.convertGPS(start.getMark1().getPosition()),
|
||||
gpsConverter.convertGPS(end.getMark1Position()));
|
||||
angle = (Math.toDegrees(angle) % 360 + 360) % 360;
|
||||
int dir = 0; //0 = top 1 = right 2 = down 3 = down
|
||||
if (angle < 315){
|
||||
if (angle > 45){
|
||||
dir ++;
|
||||
}
|
||||
if (angle > 135){
|
||||
dir ++;
|
||||
}
|
||||
if (angle > 225){
|
||||
dir ++;
|
||||
}
|
||||
}
|
||||
|
||||
end1.setMaterial(nextMark);
|
||||
if(end.getMark2() != null) {
|
||||
Shape3D end2 = view3D.getShape(end.getMark2().getSourceID()).getMesh();
|
||||
end2.setMaterial(nextMark);
|
||||
}
|
||||
Mark startMark1 = end.getMark1();
|
||||
Mark startMark2 = end.getMark2();
|
||||
|
||||
setNextMarkArrowDirection(startMark1, startMark2, end.getRoundingType(), dir);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -922,14 +1057,18 @@ public class RaceViewController extends Controller {
|
||||
if(boat.getHealth()<=0){
|
||||
//Boat is dead. Don't check it anymore for hp
|
||||
fp.displayDeath(fp.getSourceID()==raceState.getPlayerBoatID());
|
||||
fp.setSourceID(0);
|
||||
try {
|
||||
raceState.getBoat(boat.getSourceID()).setStatus(BoatStatusEnum.DNF);
|
||||
Annotation3D sharks = new Annotation3D(Assets3D.getSharks());
|
||||
sharks.setX(gpsConverter.convertGPS(boat.getPosition()).getX());
|
||||
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());
|
||||
} catch (BoatNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
fp.setSourceID(0);
|
||||
}
|
||||
else
|
||||
//Speed up tick when <=10 hp
|
||||
@@ -1116,4 +1255,85 @@ public class RaceViewController extends Controller {
|
||||
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,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;
|
||||
@@ -16,12 +20,66 @@ import java.net.URL;
|
||||
public class Assets3D {
|
||||
|
||||
public static MeshView[] sails;
|
||||
public static MeshView[] sea;
|
||||
public static MeshView[] seagull;
|
||||
public static Subject3D windArrow;
|
||||
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(){
|
||||
loadSails();
|
||||
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(){
|
||||
@@ -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(){
|
||||
String path = "assets/V1.4 Boat.x3d";
|
||||
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));
|
||||
@@ -52,6 +145,11 @@ public class Assets3D {
|
||||
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){
|
||||
X3dModelImporter x3dModelImporter = new X3dModelImporter();
|
||||
URL asset = Assets3D.class.getClassLoader().getResource(path);
|
||||
@@ -68,4 +166,8 @@ public class Assets3D {
|
||||
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;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.geometry.Point3D;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
@@ -16,7 +17,7 @@ import visualiser.utils.PerlinNoiseGenerator;
|
||||
/**
|
||||
* Creates a SeaSurface
|
||||
*/
|
||||
public class SeaSurface extends Subject3D {
|
||||
public class SeaSurface extends Annotation3D {
|
||||
private static Image image;
|
||||
|
||||
/**
|
||||
@@ -26,7 +27,7 @@ public class SeaSurface extends Subject3D {
|
||||
* @param freq frequency the perlin noise is to be generated at
|
||||
*/
|
||||
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"));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -111,4 +111,11 @@ public class GPSConverter {
|
||||
return Math.atan2(coord2.getX() - coord1.getX(), coord2.getY() - coord1.getY());
|
||||
}
|
||||
|
||||
public double getLongitudeFactor() {
|
||||
return longitudeFactor;
|
||||
}
|
||||
|
||||
public double getLatitudeFactor() {
|
||||
return latitudeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user