Merge remote-tracking branch 'origin/master' into raceLength
This commit is contained in:
@@ -160,7 +160,7 @@ public class InGameLobbyController extends Controller {
|
||||
// subjects.add(subject);
|
||||
Shape3D mesh = Assets3D.getBoat();
|
||||
PhongMaterial boatColorMat = new PhongMaterial(boat.getColor());
|
||||
mesh.setMaterial(boatColorMat);
|
||||
//mesh.setMaterial(boatColorMat);
|
||||
Subject3D subject = new Subject3D(mesh, 0);
|
||||
subjects.add(subject);
|
||||
|
||||
@@ -191,6 +191,8 @@ public class InGameLobbyController extends Controller {
|
||||
public void handle(long now) {
|
||||
subject.setHeading(subject.getHeading().getAngle() + 0.1);
|
||||
sailsSubject.setHeading(subject.getHeading().getAngle() + 0.1);
|
||||
sailsSubject.setX(subject.getX());
|
||||
sailsSubject.setZ(subject.getZ());
|
||||
}
|
||||
};
|
||||
rotate.start();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -61,7 +62,12 @@ public class RaceViewController extends Controller {
|
||||
private boolean isTutorial = false;
|
||||
private String keyToPress;
|
||||
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;
|
||||
|
||||
@@ -93,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.
|
||||
@@ -204,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}.
|
||||
*/
|
||||
@@ -226,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());
|
||||
@@ -268,6 +350,9 @@ public class RaceViewController extends Controller {
|
||||
view3D.addPointLight(pointLight);
|
||||
canvasBase.add(view3D, 0, 0);
|
||||
|
||||
windCompass = new WindCompass(view3D, this.raceState.windProperty());
|
||||
arrowPane.getChildren().add(windCompass);
|
||||
|
||||
// Set up projection from GPS to view
|
||||
RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource();
|
||||
final GPSConverter gpsConverter = new GPSConverter(raceData, 450, 450);
|
||||
@@ -320,15 +405,16 @@ 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());
|
||||
mesh.setMaterial(boatColorMat);
|
||||
//mesh.setMaterial(boatColorMat);
|
||||
Subject3D boatModel = new Subject3D(mesh, boat.getSourceID());
|
||||
|
||||
viewSubjects.add(boatModel);
|
||||
@@ -723,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
|
||||
*/
|
||||
|
||||
@@ -16,9 +16,12 @@ import java.net.URL;
|
||||
public class Assets3D {
|
||||
|
||||
public static MeshView[] sails;
|
||||
public static Subject3D windArrow;
|
||||
public static Subject3D compass;
|
||||
|
||||
public static void loadAssets(){
|
||||
loadSails();
|
||||
loadWindArrow();
|
||||
}
|
||||
|
||||
private static void loadSails(){
|
||||
@@ -26,7 +29,7 @@ public class Assets3D {
|
||||
ObjModelImporter objModelImporter = new ObjModelImporter();
|
||||
|
||||
for (int i = 0; i < sails.length; i++){
|
||||
String path = String.format("assets/Sails/V1.3 Sail_%06d.obj", i + 1);
|
||||
String path = String.format("assets/Sails/V1.5 Sail_%06d.obj", i + 1);
|
||||
URL asset = Assets3D.class.getClassLoader().getResource(path);
|
||||
objModelImporter.read(asset);
|
||||
if (objModelImporter.getImport().length > 0) {
|
||||
@@ -38,15 +41,26 @@ public class Assets3D {
|
||||
}
|
||||
|
||||
public static Shape3D getBoat(){
|
||||
String path = "assets/V1.4 Boat.x3d";
|
||||
return loadX3d(path);
|
||||
}
|
||||
|
||||
private static void loadWindArrow(){
|
||||
String compassPath = "assets/wind_compass.x3d";
|
||||
compass = new Annotation3D(loadX3d(compassPath));
|
||||
String arrowPath = "assets/wind_arrow.x3d";
|
||||
windArrow = new Annotation3D(loadX3d(arrowPath));
|
||||
}
|
||||
|
||||
private static Shape3D loadX3d(String path){
|
||||
X3dModelImporter x3dModelImporter = new X3dModelImporter();
|
||||
String path = "assets/V1.3 Complete Boat without Sail and Rotated.x3d";
|
||||
URL asset = Assets3D.class.getClassLoader().getResource(path);
|
||||
x3dModelImporter.read(asset);
|
||||
if (x3dModelImporter.getImport().length > 0) {
|
||||
//if (x3dModelImporter.getImport()[0] instanceof MeshView) {
|
||||
Group g = (Group)((Group)((Group) x3dModelImporter.getImport()[0]).getChildren().get(0)).getChildren().get(0);
|
||||
Shape3D boat = (Shape3D)g.getChildren().get(0);
|
||||
return boat;
|
||||
Shape3D shape = (Shape3D)g.getChildren().get(0);
|
||||
return shape;
|
||||
/*} else {
|
||||
System.err.println("Boat is not a Mesh View 0.0");
|
||||
}*/
|
||||
|
||||
@@ -77,14 +77,26 @@ public class Subject3D {
|
||||
position.setX(x);
|
||||
}
|
||||
|
||||
public double getX(){
|
||||
return position.getX();
|
||||
}
|
||||
|
||||
public void setY(double y) {
|
||||
position.setY(y);
|
||||
}
|
||||
|
||||
public double getY(){
|
||||
return position.getY();
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
position.setZ(z);
|
||||
}
|
||||
|
||||
public double getZ(){
|
||||
return position.getZ();
|
||||
}
|
||||
|
||||
public void setHeading(double angle) {
|
||||
heading.setAngle(angle);
|
||||
}
|
||||
|
||||
@@ -349,6 +349,10 @@ public class View3D extends Pane {
|
||||
this.yaw.setAngle(yaw);
|
||||
}
|
||||
|
||||
public double getYaw(){
|
||||
return this.yaw.getAngle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set elevation of camera
|
||||
* @param pitch in degrees
|
||||
@@ -357,6 +361,10 @@ public class View3D extends Pane {
|
||||
this.pitch.setAngle(-pitch);
|
||||
}
|
||||
|
||||
public double getPitch(){
|
||||
return this.pitch.getAngle();
|
||||
}
|
||||
|
||||
public void addAmbientLight(AmbientLight ambientLight) {
|
||||
this.world.getChildren().add(ambientLight);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package visualiser.layout;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import shared.model.Wind;
|
||||
|
||||
/**
|
||||
* Created by Gondr on 25/09/2017.
|
||||
*/
|
||||
public class WindCompass extends View3D {
|
||||
Subject3D compass;
|
||||
Subject3D windArrow;
|
||||
View3D view3D;
|
||||
Property<Wind> wind;
|
||||
|
||||
AnimationTimer followView3D = new AnimationTimer() {
|
||||
@Override
|
||||
public void handle(long now) {
|
||||
setYaw(180+ view3D.getYaw());
|
||||
setPitch(30 - view3D.getPitch());
|
||||
windArrow.setHeading(wind.getValue().getWindDirection().degrees());
|
||||
}
|
||||
};
|
||||
|
||||
public WindCompass(View3D view3D, Property<Wind> wind){
|
||||
super();
|
||||
this.wind = wind;
|
||||
this.view3D = view3D;
|
||||
this.followView3D.start();
|
||||
ObservableList<Subject3D> subjects = FXCollections.observableArrayList();
|
||||
this.setItems(subjects);
|
||||
compass = Assets3D.compass;
|
||||
windArrow = Assets3D.windArrow;
|
||||
subjects.addAll(compass, windArrow);
|
||||
this.setDistance(30);
|
||||
this.setPitch(90);
|
||||
this.setYaw(180);
|
||||
}
|
||||
|
||||
public void setHeading(double heading){
|
||||
windArrow.setHeading(heading);
|
||||
}
|
||||
|
||||
public void setCompassPitch(double pitch){
|
||||
setPitch(90d + pitch);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user