|
|
|
|
@ -471,15 +471,18 @@ public class RaceViewController extends Controller {
|
|
|
|
|
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)));
|
|
|
|
|
|
|
|
|
|
boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> changeNextMark(curr)));
|
|
|
|
|
} else {
|
|
|
|
|
viewSubjects.add(boatModel);
|
|
|
|
|
boatModel.getMesh().toFront();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Create health effect
|
|
|
|
|
@ -494,9 +497,22 @@ public class RaceViewController extends Controller {
|
|
|
|
|
sails3D.setMaterial(boatColorMat);
|
|
|
|
|
sailsSubject.setXRot(0d);
|
|
|
|
|
sailsSubject.setHeading(visualiserRace.getVisualiserRaceState().getWindDirection().degrees());
|
|
|
|
|
|
|
|
|
|
viewSubjects.add(sailsSubject);
|
|
|
|
|
|
|
|
|
|
//next mark indicator
|
|
|
|
|
changeNextMark(boat.getCurrentLeg());
|
|
|
|
|
viewSubjects.add(Assets3D.ccwNextArrow);
|
|
|
|
|
viewSubjects.add(Assets3D.cwNextArrow);
|
|
|
|
|
|
|
|
|
|
AnimationTimer rotateArrows = new AnimationTimer() {
|
|
|
|
|
@Override
|
|
|
|
|
public void handle(long now) {
|
|
|
|
|
Assets3D.ccwNextArrow.setHeading(Assets3D.ccwNextArrow.getHeading().getAngle() - 3.0);
|
|
|
|
|
Assets3D.cwNextArrow.setHeading(Assets3D.cwNextArrow.getHeading().getAngle() + 3.0);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
rotateArrows.start();
|
|
|
|
|
|
|
|
|
|
AnimationTimer sailsFollowBoat = new AnimationTimer() {
|
|
|
|
|
double sailCurrent = visualiserRace.getVisualiserRaceState().getWindDirection().degrees();
|
|
|
|
|
boolean canLuff = true;
|
|
|
|
|
@ -555,7 +571,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();
|
|
|
|
|
@ -581,18 +597,6 @@ public class RaceViewController extends Controller {
|
|
|
|
|
|
|
|
|
|
//next mark indicator
|
|
|
|
|
//Material markColor = new PhongMaterial(new Color(0.15,0.9,0.2,1));
|
|
|
|
|
changeNextMark(boat.getCurrentLeg());
|
|
|
|
|
viewSubjects.add(Assets3D.ccwNextArrow);
|
|
|
|
|
viewSubjects.add(Assets3D.cwNextArrow);
|
|
|
|
|
|
|
|
|
|
AnimationTimer rotateArrows = new AnimationTimer() {
|
|
|
|
|
@Override
|
|
|
|
|
public void handle(long now) {
|
|
|
|
|
Assets3D.ccwNextArrow.setHeading(Assets3D.ccwNextArrow.getHeading().getAngle() - 3.0);
|
|
|
|
|
Assets3D.cwNextArrow.setHeading(Assets3D.cwNextArrow.getHeading().getAngle() + 3.0);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
rotateArrows.start();
|
|
|
|
|
/*CompoundMark nextMark = boat.getCurrentLeg().getEndCompoundMark();
|
|
|
|
|
|
|
|
|
|
view3D.getShape(nextMark.getMark1().getSourceID()).getMesh().setMaterial(markColor);
|
|
|
|
|
@ -604,7 +608,6 @@ public class RaceViewController extends Controller {
|
|
|
|
|
viewSubjects.add(shockwave);
|
|
|
|
|
|
|
|
|
|
//boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> swapColours(curr)));
|
|
|
|
|
boat.legProperty().addListener((o, prev, curr) -> Platform.runLater(() -> changeNextMark(curr)));
|
|
|
|
|
boat.hasCollidedProperty().addListener((o, prev, curr) -> Platform.runLater(() -> showCollision(boat, shockwave)));
|
|
|
|
|
}
|
|
|
|
|
// Fix initial bird's-eye position
|
|
|
|
|
@ -749,6 +752,71 @@ public class RaceViewController extends Controller {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
System.out.println(direction);
|
|
|
|
|
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();
|
|
|
|
|
@ -757,47 +825,30 @@ public class RaceViewController extends Controller {
|
|
|
|
|
if (start == null || end == null ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
Leg legOfInterest;
|
|
|
|
|
for (int i = 0; i < raceState.getLegs().size(); i ++){
|
|
|
|
|
if (raceState.getLegs().get(i) == leg){
|
|
|
|
|
legOfInterest = raceState.getLegs().get(i);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//find direction coming
|
|
|
|
|
double angle = gpsConverter.getAngle(gpsConverter.convertGPS(start.getMark1().getPosition()),
|
|
|
|
|
gpsConverter.convertGPS(end.getMark1Position()));
|
|
|
|
|
angle = (Math.toDegrees(angle) % 360 + 360) % 360;
|
|
|
|
|
System.out.println(angle);
|
|
|
|
|
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 ++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CompoundMark nextMark = leg.getStartCompoundMark();
|
|
|
|
|
CompoundMark dirMark = leg.getEndCompoundMark();*/
|
|
|
|
|
|
|
|
|
|
boolean firstMarkCCW = end.getRoundingType() == RoundingType.Port;
|
|
|
|
|
// double angle = gpsConverter.getAngle(gpsConverter.convertGPS(dirMark.getMark1().getPosition()),
|
|
|
|
|
// gpsConverter.convertGPS(nextMark.getMark1().getPosition()));
|
|
|
|
|
// if (nextMark.getRoundingType() == RoundingType.Port){
|
|
|
|
|
// if (angle < 90 || angle >= 270){
|
|
|
|
|
// firstMarkCCW = false;
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// if (angle < 270 && angle >= 90){
|
|
|
|
|
// firstMarkCCW = false;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
Mark startMark1 = end.getMark1();
|
|
|
|
|
Mark startMark2 = end.getMark2();
|
|
|
|
|
|
|
|
|
|
if (firstMarkCCW){
|
|
|
|
|
Assets3D.ccwNextArrow.setX(gpsConverter.convertGPS(startMark1.getPosition()).getX());
|
|
|
|
|
Assets3D.ccwNextArrow.setZ(gpsConverter.convertGPS(startMark1.getPosition()).getY());
|
|
|
|
|
if (end.getMark2() != null) {
|
|
|
|
|
Assets3D.cwNextArrow.setX(gpsConverter.convertGPS(startMark2.getPosition()).getX());
|
|
|
|
|
Assets3D.cwNextArrow.setZ(gpsConverter.convertGPS(startMark2.getPosition()).getY());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Assets3D.cwNextArrow.setX(gpsConverter.convertGPS(startMark1.getPosition()).getX());
|
|
|
|
|
Assets3D.cwNextArrow.setZ(gpsConverter.convertGPS(startMark1.getPosition()).getY());
|
|
|
|
|
if (end.getMark2() != null) {
|
|
|
|
|
Assets3D.ccwNextArrow.setX(gpsConverter.convertGPS(startMark2.getPosition()).getX());
|
|
|
|
|
Assets3D.ccwNextArrow.setZ(gpsConverter.convertGPS(startMark2.getPosition()).getY());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setNextMarkArrowDirection(startMark1, startMark2, end.getRoundingType(), dir);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|