|
|
|
|
@ -1,6 +1,9 @@
|
|
|
|
|
package visualiser.Controllers;
|
|
|
|
|
|
|
|
|
|
import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
|
|
|
|
|
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
|
|
|
|
|
import eu.hansolo.medusa.*;
|
|
|
|
|
import eu.hansolo.medusa.events.UpdateEvent;
|
|
|
|
|
import javafx.animation.AnimationTimer;
|
|
|
|
|
import javafx.application.Platform;
|
|
|
|
|
import javafx.collections.FXCollections;
|
|
|
|
|
@ -20,6 +23,7 @@ import javafx.scene.layout.StackPane;
|
|
|
|
|
import javafx.scene.paint.Color;
|
|
|
|
|
import javafx.scene.paint.Material;
|
|
|
|
|
import javafx.scene.paint.PhongMaterial;
|
|
|
|
|
import javafx.scene.paint.Stop;
|
|
|
|
|
import javafx.scene.shape.MeshView;
|
|
|
|
|
import javafx.scene.shape.Shape3D;
|
|
|
|
|
import javafx.scene.transform.Translate;
|
|
|
|
|
@ -39,10 +43,7 @@ import visualiser.utils.GPSConverter;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.net.URL;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Optional;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.logging.Level;
|
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
|
|
|
|
@ -63,6 +64,10 @@ public class RaceViewController extends Controller {
|
|
|
|
|
private View3D view3D;
|
|
|
|
|
private WindCompass windCompass;
|
|
|
|
|
private ObservableList<Subject3D> viewSubjects;
|
|
|
|
|
private Gauge gauge;
|
|
|
|
|
private FGauge fGauge;
|
|
|
|
|
private long positionDelay = 1000;
|
|
|
|
|
private long positionTime = 0;
|
|
|
|
|
private ResizableRaceCanvas raceCanvas;
|
|
|
|
|
private boolean mapToggle = true;
|
|
|
|
|
|
|
|
|
|
@ -94,6 +99,8 @@ public class RaceViewController extends Controller {
|
|
|
|
|
private @FXML Label tutorialText;
|
|
|
|
|
private @FXML AnchorPane infoWrapper;
|
|
|
|
|
private @FXML AnchorPane lineChartWrapper;
|
|
|
|
|
private @FXML StackPane speedPane;
|
|
|
|
|
private @FXML AnchorPane raceAnchorPane;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Displays a specified race.
|
|
|
|
|
@ -205,6 +212,78 @@ public class RaceViewController extends Controller {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create speedometer
|
|
|
|
|
*/
|
|
|
|
|
private void initialiseSpeedometer() {
|
|
|
|
|
//Create the Medusa Gauge
|
|
|
|
|
gauge = GaugeBuilder.create()
|
|
|
|
|
.prefSize(200,200)
|
|
|
|
|
.foregroundBaseColor(Color.WHITE)
|
|
|
|
|
.title("Title")
|
|
|
|
|
.subTitle("Speed")
|
|
|
|
|
.unit("Knots")
|
|
|
|
|
.decimals(2)
|
|
|
|
|
.lcdVisible(true)
|
|
|
|
|
.lcdDesign(LcdDesign.STANDARD)
|
|
|
|
|
.lcdFont(LcdFont.DIGITAL_BOLD)
|
|
|
|
|
.scaleDirection(Gauge.ScaleDirection.CLOCKWISE)
|
|
|
|
|
.minValue(0)
|
|
|
|
|
.maxValue(50)
|
|
|
|
|
.startAngle(320)
|
|
|
|
|
.angleRange(280)
|
|
|
|
|
.tickLabelDecimals(0)
|
|
|
|
|
.tickLabelLocation(TickLabelLocation.INSIDE)
|
|
|
|
|
.tickLabelOrientation(TickLabelOrientation.ORTHOGONAL)
|
|
|
|
|
.onlyFirstAndLastTickLabelVisible(false)
|
|
|
|
|
.tickLabelSectionsVisible(false)
|
|
|
|
|
.tickLabelColor(Color.BLACK)
|
|
|
|
|
.tickMarkSectionsVisible(false)
|
|
|
|
|
.majorTickMarksVisible(true)
|
|
|
|
|
.majorTickMarkType(TickMarkType.TRAPEZOID)
|
|
|
|
|
.mediumTickMarksVisible(false)
|
|
|
|
|
.mediumTickMarkType(TickMarkType.LINE)
|
|
|
|
|
.minorTickMarksVisible(true)
|
|
|
|
|
.minorTickMarkType(TickMarkType.LINE)
|
|
|
|
|
.ledVisible(false)
|
|
|
|
|
.ledType(Gauge.LedType.STANDARD)
|
|
|
|
|
.ledColor(Color.rgb(255, 200, 0))
|
|
|
|
|
.ledBlinking(false)
|
|
|
|
|
.needleShape(Gauge.NeedleShape.ANGLED)
|
|
|
|
|
.needleSize(Gauge.NeedleSize.STANDARD)
|
|
|
|
|
.needleColor(Color.CRIMSON)
|
|
|
|
|
.startFromZero(false)
|
|
|
|
|
.returnToZero(false)
|
|
|
|
|
.knobType(Gauge.KnobType.METAL)
|
|
|
|
|
.knobColor(Color.LIGHTGRAY)
|
|
|
|
|
.interactive(false)
|
|
|
|
|
.thresholdVisible(true)
|
|
|
|
|
.threshold(50)
|
|
|
|
|
.thresholdColor(Color.RED)
|
|
|
|
|
.checkThreshold(true)
|
|
|
|
|
.gradientBarEnabled(true)
|
|
|
|
|
.gradientBarStops(new Stop(0.0, Color.BLUE),
|
|
|
|
|
new Stop(0.25, Color.CYAN),
|
|
|
|
|
new Stop(0.5, Color.LIME),
|
|
|
|
|
new Stop(0.75, Color.YELLOW),
|
|
|
|
|
new Stop(1.0, Color.RED))
|
|
|
|
|
.markersVisible(true)
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Create a gauge with a frame and background that utilizes a Medusa gauge
|
|
|
|
|
fGauge = FGaugeBuilder
|
|
|
|
|
.create()
|
|
|
|
|
.prefSize(200, 200)
|
|
|
|
|
.gauge(gauge)
|
|
|
|
|
.gaugeDesign(GaugeDesign.METAL)
|
|
|
|
|
.gaugeBackground(GaugeDesign.GaugeBackground.CARBON)
|
|
|
|
|
.foregroundVisible(true)
|
|
|
|
|
.build();
|
|
|
|
|
speedPane.getChildren().add(fGauge);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialises the various UI components to listen to the {@link #visualiserRace}.
|
|
|
|
|
*/
|
|
|
|
|
@ -227,7 +306,9 @@ public class RaceViewController extends Controller {
|
|
|
|
|
initialiseInfoTable();
|
|
|
|
|
initialiseView3D(this.visualiserRace);
|
|
|
|
|
initialiseRaceClock();
|
|
|
|
|
initialiseSpeedometer();
|
|
|
|
|
raceTimer(); // start the timer
|
|
|
|
|
speedometerLoop();
|
|
|
|
|
new Sparkline(this.raceState, this.sparklineChart);
|
|
|
|
|
timeZone.setText(this.raceState.getRaceClock().getTimeZone());
|
|
|
|
|
arrowController.setWindProperty(this.raceState.windProperty());
|
|
|
|
|
@ -324,11 +405,12 @@ public class RaceViewController extends Controller {
|
|
|
|
|
|
|
|
|
|
// Position and add each boat to view
|
|
|
|
|
for(VisualiserBoat boat: race.getVisualiserRaceState().getBoats()) {
|
|
|
|
|
/*if(boat.getSourceID() == race.getVisualiserRaceState().getPlayerBoatID()) {
|
|
|
|
|
mesh = new MeshView(importer.getImport());
|
|
|
|
|
} else {
|
|
|
|
|
mesh = new MeshView(importerBurgerBoat.getImport());
|
|
|
|
|
}*/
|
|
|
|
|
// MeshView mesh;
|
|
|
|
|
// if(boat.getSourceID() == race.getVisualiserRaceState().getPlayerBoatID()) {
|
|
|
|
|
// mesh = new MeshView(importer.getImport());
|
|
|
|
|
// } else {
|
|
|
|
|
// mesh = new MeshView(importerBurgerBoat.getImport());
|
|
|
|
|
// }
|
|
|
|
|
Shape3D mesh = Assets3D.getBoat();
|
|
|
|
|
|
|
|
|
|
PhongMaterial boatColorMat = new PhongMaterial(boat.getColor());
|
|
|
|
|
@ -727,6 +809,39 @@ public class RaceViewController extends Controller {
|
|
|
|
|
}.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Animation timer loop for the speedometer
|
|
|
|
|
*/
|
|
|
|
|
private void speedometerLoop(){
|
|
|
|
|
new AnimationTimer(){
|
|
|
|
|
@Override
|
|
|
|
|
public void handle(long arg0){
|
|
|
|
|
if (raceState.getRaceStatusEnum() == RaceStatusEnum.FINISHED) {
|
|
|
|
|
stop(); // stop the timer
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
//Set the current speed value of the boat
|
|
|
|
|
gauge.setValue(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed());
|
|
|
|
|
fGauge.getGauge().setValue(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed());
|
|
|
|
|
|
|
|
|
|
//Create list with sorted boat placements
|
|
|
|
|
List<VisualiserBoat> boatList = boatInfoTable.getItems();
|
|
|
|
|
for (VisualiserBoat boat : boatList){
|
|
|
|
|
if(raceState.getPlayerBoatID()==boat.getSourceID()){
|
|
|
|
|
//Set boat current placement value as title of speedometer
|
|
|
|
|
gauge.titleProperty().setValue("Position: " + (boatInfoTable.getItems().indexOf(boat)+1));
|
|
|
|
|
fGauge.getGauge().titleProperty().setValue("Position: " + (boatInfoTable.getItems().indexOf(boat)+1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (BoatNotFoundException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* toggles if the info table is shown
|
|
|
|
|
*/
|
|
|
|
|
|