# Conflicts: # racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.javamain
commit
8a6997f29b
@ -0,0 +1,38 @@
|
|||||||
|
package network.MessageDecoders;
|
||||||
|
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static network.Utils.ByteConverter.bytesToInt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decoder for {@link BoatState} messages
|
||||||
|
*/
|
||||||
|
public class BoatStateDecoder implements MessageDecoder {
|
||||||
|
/**
|
||||||
|
* Decoded BoatState message
|
||||||
|
*/
|
||||||
|
private BoatState message;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||||
|
byte[] sourceID = Arrays.copyOfRange(encodedMessage, 0, 4);
|
||||||
|
byte boatHealth = encodedMessage[4];
|
||||||
|
|
||||||
|
// Unpack bytes into BoatState
|
||||||
|
this.message = new BoatState(
|
||||||
|
bytesToInt(sourceID),
|
||||||
|
boatHealth
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return BoatState
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoatState getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package network.MessageEncoders;
|
||||||
|
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static network.Utils.ByteConverter.intToBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder for {@link BoatState} message
|
||||||
|
*/
|
||||||
|
public class BoatStateEncoder implements MessageEncoder {
|
||||||
|
@Override
|
||||||
|
public byte[] encode(AC35Data message) throws InvalidMessageException {
|
||||||
|
// Downcast message
|
||||||
|
BoatState boatState = (BoatState)message;
|
||||||
|
|
||||||
|
//Serialise message
|
||||||
|
byte[] sourceID = intToBytes(boatState.getSourceID());
|
||||||
|
byte boatHealth = (byte)boatState.getBoatHealth();
|
||||||
|
|
||||||
|
// Pack bytes into string
|
||||||
|
ByteBuffer boatStateMessage = ByteBuffer.allocate(5);
|
||||||
|
boatStateMessage.put(sourceID);
|
||||||
|
boatStateMessage.put(boatHealth);
|
||||||
|
|
||||||
|
// Return byte string
|
||||||
|
return boatStateMessage.array();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package network.Messages;
|
||||||
|
|
||||||
|
import network.Messages.Enums.MessageType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the information in a BoatState message according to protocol meeting
|
||||||
|
*/
|
||||||
|
public class BoatState extends AC35Data {
|
||||||
|
/**
|
||||||
|
* Source ID of boat described in message
|
||||||
|
*/
|
||||||
|
private int sourceID;
|
||||||
|
/**
|
||||||
|
* Health between 0-100 of boat with above source ID
|
||||||
|
*/
|
||||||
|
private int boatHealth;
|
||||||
|
|
||||||
|
public BoatState(int sourceID, int boatHealth) {
|
||||||
|
super(MessageType.BOATSTATE);
|
||||||
|
this.sourceID = sourceID;
|
||||||
|
this.boatHealth = boatHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSourceID() {
|
||||||
|
return sourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBoatHealth() {
|
||||||
|
return boatHealth;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package visualiser.Commands.VisualiserRaceCommands;
|
||||||
|
|
||||||
|
import mock.model.commandFactory.Command;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
import shared.exceptions.BoatNotFoundException;
|
||||||
|
import visualiser.model.VisualiserBoat;
|
||||||
|
import visualiser.model.VisualiserRaceState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates boats on visualiser when their health changes
|
||||||
|
*/
|
||||||
|
public class BoatStateCommand implements Command {
|
||||||
|
private BoatState boatState;
|
||||||
|
private VisualiserRaceState visualiserRace;
|
||||||
|
|
||||||
|
public BoatStateCommand(BoatState boatState, VisualiserRaceState visualiserRace) {
|
||||||
|
this.boatState = boatState;
|
||||||
|
this.visualiserRace = visualiserRace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
try {
|
||||||
|
VisualiserBoat boat = visualiserRace.getBoat(boatState.getSourceID());
|
||||||
|
boat.setHealth(boatState.getBoatHealth());
|
||||||
|
} catch (BoatNotFoundException e) {
|
||||||
|
// Fail silently
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
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.geometry.Point3D;
|
||||||
|
import javafx.scene.AmbientLight;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.paint.PhongMaterial;
|
||||||
|
import javafx.scene.shape.Cylinder;
|
||||||
|
import javafx.scene.shape.MeshView;
|
||||||
|
import javafx.scene.shape.Shape3D;
|
||||||
|
import javafx.scene.transform.Rotate;
|
||||||
|
import shared.model.Bearing;
|
||||||
|
import shared.model.CompoundMark;
|
||||||
|
import shared.model.GPSCoordinate;
|
||||||
|
import visualiser.layout.Annotation3D;
|
||||||
|
import visualiser.layout.Assets3D;
|
||||||
|
import visualiser.layout.Subject3D;
|
||||||
|
import visualiser.layout.View3D;
|
||||||
|
import visualiser.model.VisualiserBoat;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
public class NextMarkController {
|
||||||
|
private @FXML StackPane arrowStackPane2d;
|
||||||
|
private @FXML StackPane arrowStackPane3d;
|
||||||
|
private @FXML Pane pane2d;
|
||||||
|
private @FXML Pane pane3d;
|
||||||
|
|
||||||
|
private VisualiserBoat boat;
|
||||||
|
|
||||||
|
public void initialiseArrowView(VisualiserBoat boat) {
|
||||||
|
this.boat = boat;
|
||||||
|
pane2d.setVisible(true);
|
||||||
|
pane3d.setVisible(false);
|
||||||
|
initialise2dArrowView();
|
||||||
|
initialise3dArrowView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialise2dArrowView() {
|
||||||
|
AnimationTimer arrow2d = new AnimationTimer() {
|
||||||
|
@Override
|
||||||
|
public void handle(long now) {
|
||||||
|
if (boat.getCurrentLeg().getEndCompoundMark() != null) {
|
||||||
|
CompoundMark target = boat.getCurrentLeg().getEndCompoundMark();
|
||||||
|
Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate());
|
||||||
|
arrowStackPane2d.setRotate(headingToMark.degrees());
|
||||||
|
} else {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
arrow2d.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialise3dArrowView() {
|
||||||
|
ObservableList<Subject3D> viewSubjects = FXCollections.observableArrayList();
|
||||||
|
String arrowPath = "assets/mark_arrow.x3d";
|
||||||
|
|
||||||
|
Shape3D arrow = Assets3D.loadX3d(arrowPath);
|
||||||
|
|
||||||
|
arrow.setScaleX(25);
|
||||||
|
arrow.setScaleY(25);
|
||||||
|
arrow.setScaleZ(100);
|
||||||
|
arrow.setRotationAxis(new Point3D(1,0,0));
|
||||||
|
|
||||||
|
arrowStackPane3d.getChildren().add(arrow);
|
||||||
|
|
||||||
|
AnimationTimer arrow3d = new AnimationTimer() {
|
||||||
|
@Override
|
||||||
|
public void handle(long now) {
|
||||||
|
if (boat.getCurrentLeg().getEndCompoundMark() != null) {
|
||||||
|
arrow.getTransforms().clear();
|
||||||
|
double zRotation = calculateZRotate();
|
||||||
|
arrow.setRotate(calculateXRotate(zRotation));
|
||||||
|
arrow.getTransforms().add(new Rotate(zRotation, new Point3D(0, 0, 1)));
|
||||||
|
} else {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
arrow3d.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show2d() {
|
||||||
|
pane3d.setVisible(false);
|
||||||
|
pane2d.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show3d() {
|
||||||
|
pane2d.setVisible(false);
|
||||||
|
pane3d.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculateZRotate() {
|
||||||
|
CompoundMark target = boat.getCurrentLeg().getEndCompoundMark();
|
||||||
|
Bearing headingToMark = GPSCoordinate.calculateBearing(boat.getPosition(), target.getAverageGPSCoordinate());
|
||||||
|
return -headingToMark.degrees() + boat.getBearing().degrees() + 180;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculateXRotate(double zRotation) {
|
||||||
|
// if (zRotation > 360) {
|
||||||
|
// zRotation -=360;
|
||||||
|
// } else if (zRotation < 0) {
|
||||||
|
// zRotation += 360;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (zRotation > 180) {
|
||||||
|
// zRotation = 360 - zRotation;
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 70;
|
||||||
|
//return 90 - 20 * Math.cos(Math.toRadians(zRotation));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
package visualiser.layout;
|
||||||
|
|
||||||
|
import javafx.geometry.Point3D;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.media.AudioClip;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.paint.PhongMaterial;
|
||||||
|
import javafx.scene.shape.*;
|
||||||
|
import javafx.scene.transform.Rotate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by zwu18 on 24/09/17.
|
||||||
|
*/
|
||||||
|
public class HealthEffect extends Subject3D {
|
||||||
|
|
||||||
|
private int sourceID;
|
||||||
|
private long currentTime;
|
||||||
|
private AudioClip warningSound = new AudioClip(this.getClass().getResource("/visualiser/sounds/warning.mp3").toExternalForm());
|
||||||
|
private AudioClip deadSound = new AudioClip(this.getClass().getResource("/visualiser/sounds/dead1.wav").toExternalForm());
|
||||||
|
|
||||||
|
public HealthEffect(int sourceID, long currentTime){
|
||||||
|
super(createEffect(), 0);
|
||||||
|
this.sourceID = sourceID;
|
||||||
|
this.currentTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the mesh view with image
|
||||||
|
* @return Mesh view
|
||||||
|
*/
|
||||||
|
private static Shape3D createEffect(){
|
||||||
|
|
||||||
|
Image image = new Image(HealthEffect.class.getClassLoader().getResourceAsStream("images/warning.png"));
|
||||||
|
|
||||||
|
Plane3D plane = new Plane3D(20, 20, 10, 10);
|
||||||
|
|
||||||
|
PhongMaterial material = new PhongMaterial();
|
||||||
|
material.setDiffuseColor(Color.web("#FFFFFF"));
|
||||||
|
material.setSpecularColor(Color.web("#000000"));
|
||||||
|
material.setDiffuseMap(image);
|
||||||
|
|
||||||
|
MeshView imageSurface = new MeshView(plane);
|
||||||
|
|
||||||
|
|
||||||
|
imageSurface.setMaterial(material);
|
||||||
|
imageSurface.setMouseTransparent(true);
|
||||||
|
//imageSurface.toFront(); this.flashInterval = flashInterval;
|
||||||
|
|
||||||
|
return imageSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotateView(Double angle, Double pivotX, Double pivotY, Double pivotZ, Point3D axis){
|
||||||
|
Rotate rotate = new Rotate(angle, axis);
|
||||||
|
rotate.setPivotX(pivotX);
|
||||||
|
rotate.setPivotY(pivotY);
|
||||||
|
rotate.setPivotZ(pivotZ);
|
||||||
|
this.getMesh().getTransforms().add(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisible(boolean bool){
|
||||||
|
this.getMesh().setVisible(bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getSourceID(){
|
||||||
|
return sourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceID(int id){
|
||||||
|
this.sourceID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display visual indication when boat dies
|
||||||
|
* @param player boolean if player is current user or not
|
||||||
|
*/
|
||||||
|
public void displayDeath(boolean player){
|
||||||
|
Image image = new Image(HealthEffect.class.getClassLoader().getResourceAsStream("images/warning2.png"));
|
||||||
|
PhongMaterial material = (PhongMaterial) this.getMesh().getMaterial();
|
||||||
|
material.setDiffuseColor(Color.web("#FFFFFF"));
|
||||||
|
material.setSpecularColor(Color.web("#000000"));
|
||||||
|
material.setDiffuseMap(image);
|
||||||
|
this.getMesh().setMaterial(material);
|
||||||
|
if(player) {
|
||||||
|
deadSound.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash the mesh view at a certain interval
|
||||||
|
* @param checkTime The current time of flash
|
||||||
|
* @param flashInterval Desired flash interval
|
||||||
|
* @param playerBoat Whether or not this effect is for the player's boat.
|
||||||
|
*/
|
||||||
|
public void flash(long checkTime, long flashInterval, boolean playerBoat){
|
||||||
|
if(checkTime >= (currentTime+flashInterval)){
|
||||||
|
this.currentTime = checkTime;
|
||||||
|
if(this.getMesh().isVisible()){
|
||||||
|
this.setVisible(false);
|
||||||
|
} else {
|
||||||
|
if(playerBoat) {
|
||||||
|
warningSound.setVolume(0.1);
|
||||||
|
warningSound.play();
|
||||||
|
}
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
package visualiser.layout;
|
||||||
|
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.WritableImage;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.scene.shape.Rectangle;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by connortaylorbrown on 21/09/17.
|
||||||
|
*/
|
||||||
|
public class HealthSlider extends Pane {
|
||||||
|
/**
|
||||||
|
* Image used to fill health slider
|
||||||
|
*/
|
||||||
|
private Image fillImage;
|
||||||
|
/**
|
||||||
|
* Size of background for image configuration
|
||||||
|
*/
|
||||||
|
private BackgroundSize backgroundSize;
|
||||||
|
/**
|
||||||
|
* Percentage of image cropped out from top
|
||||||
|
*/
|
||||||
|
private double crop;
|
||||||
|
|
||||||
|
public HealthSlider(Image fillImage) {
|
||||||
|
this.fillImage = fillImage;
|
||||||
|
this.crop = 1;
|
||||||
|
this.backgroundSize = new BackgroundSize(
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
drawSlider();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCrop(double crop) {
|
||||||
|
this.crop = crop;
|
||||||
|
drawSlider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawSlider() {
|
||||||
|
int top = Math.max(0,(int)(fillImage.getHeight() - crop * fillImage.getHeight()));
|
||||||
|
|
||||||
|
WritableImage croppedImage = new WritableImage(
|
||||||
|
fillImage.getPixelReader(),
|
||||||
|
0,
|
||||||
|
top,
|
||||||
|
(int)fillImage.getWidth(),
|
||||||
|
(int)fillImage.getHeight() - top
|
||||||
|
);
|
||||||
|
|
||||||
|
BackgroundImage backgroundImage = new BackgroundImage(
|
||||||
|
croppedImage,
|
||||||
|
BackgroundRepeat.NO_REPEAT,
|
||||||
|
BackgroundRepeat.NO_REPEAT,
|
||||||
|
BackgroundPosition.CENTER,
|
||||||
|
backgroundSize
|
||||||
|
);
|
||||||
|
|
||||||
|
this.setBackground(new Background(backgroundImage));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd">
|
||||||
|
<X3D version="3.0" profile="Immersive" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.0.xsd">
|
||||||
|
<head>
|
||||||
|
<meta name="filename" content="Mark Arrow V1.3.x3d" />
|
||||||
|
<meta name="generator" content="Blender 2.77 (sub 0)" />
|
||||||
|
</head>
|
||||||
|
<Scene>
|
||||||
|
<NavigationInfo headlight="true"
|
||||||
|
visibilityLimit="0.0"
|
||||||
|
type='"EXAMINE", "ANY"'
|
||||||
|
avatarSize="0.25, 1.75, 0.75"
|
||||||
|
/>
|
||||||
|
<Background DEF="WO_World"
|
||||||
|
groundColor="0.051 0.051 0.051"
|
||||||
|
skyColor="0.051 0.051 0.051"
|
||||||
|
/>
|
||||||
|
<Transform DEF="Cube_TRANSFORM"
|
||||||
|
translation="0.000000 0.000000 0.000000"
|
||||||
|
scale="1.000000 1.000000 1.000000"
|
||||||
|
rotation="0.000000 0.707107 0.707107 3.141593"
|
||||||
|
>
|
||||||
|
<Transform DEF="Cube_ifs_TRANSFORM"
|
||||||
|
translation="0.000000 0.000000 0.000000"
|
||||||
|
scale="1.000000 1.000000 1.000000"
|
||||||
|
rotation="1.000000 0.000000 0.000000 0.000000"
|
||||||
|
>
|
||||||
|
<Group DEF="group_ME_Cube">
|
||||||
|
<Shape>
|
||||||
|
<Appearance>
|
||||||
|
<ImageTexture DEF="IM_Material_Diffuse_Color_002"
|
||||||
|
url='"textures/Material Diffuse Color.002" "Material Diffuse Color.002" "D:/Storage/3D Models/Misc/SENG302/Mark Arrow/textures/Material Diffuse Color.002"'
|
||||||
|
/>
|
||||||
|
<TextureTransform
|
||||||
|
translation="0.000000 0.000000"
|
||||||
|
scale="1.000000 1.000000"
|
||||||
|
rotation="0.000000"
|
||||||
|
/>
|
||||||
|
<Material DEF="MA_Material"
|
||||||
|
diffuseColor="0.800 0.800 0.800"
|
||||||
|
specularColor="0.401 0.401 0.401"
|
||||||
|
emissiveColor="0.000 0.000 0.000"
|
||||||
|
ambientIntensity="0.333"
|
||||||
|
shininess="0.098"
|
||||||
|
transparency="0.0"
|
||||||
|
/>
|
||||||
|
</Appearance>
|
||||||
|
<IndexedFaceSet solid="true"
|
||||||
|
texCoordIndex="0 1 2 -1 3 4 5 -1 6 7 8 9 -1 10 11 12 -1 13 14 15 -1 16 17 18 19 -1 20 21 22 -1 23 24 25 -1 26 27 28 29 -1 30 31 32 -1 33 34 35 -1 36 37 38 39 -1 "
|
||||||
|
coordIndex="4 1 7 -1 2 0 8 -1 1 0 2 3 -1 1 3 7 -1 8 0 9 -1 0 1 4 9 -1 4 7 6 -1 2 8 5 -1 6 3 2 5 -1 6 7 3 -1 8 9 5 -1 4 6 5 9 -1 "
|
||||||
|
>
|
||||||
|
<Coordinate DEF="coords_ME_Cube"
|
||||||
|
point="1.000000 -0.000000 -0.100000 1.000000 -0.000001 0.100000 0.000000 2.000000 -0.100000 0.000000 2.000000 0.100000 0.000000 -2.000000 0.100000 -1.000000 -0.000000 -0.100000 -1.000000 -0.000001 0.100000 0.000000 -0.000000 0.100000 0.000000 0.000000 -0.100000 0.000000 -2.000000 -0.100000 "
|
||||||
|
/>
|
||||||
|
<TextureCoordinate point="0.9999 0.0001 0.7826 0.0001 0.8260 0.0870 0.6522 0.1934 0.7826 0.3673 0.8260 0.2803 0.4348 0.1740 0.4348 0.1934 0.6522 0.1934 0.6522 0.1740 0.7826 0.0001 0.6522 0.1740 0.8260 0.0870 0.8260 0.2803 0.7826 0.3673 0.9999 0.3673 0.4348 0.1934 0.4348 0.1740 0.2174 0.1740 0.2174 0.1934 0.9999 0.0001 0.8260 0.0870 0.8695 0.1740 0.6522 0.1934 0.8260 0.2803 0.8695 0.1934 0.8695 0.1740 0.6522 0.1740 0.6522 0.1934 0.8695 0.1934 0.8695 0.1740 0.8260 0.0870 0.6522 0.1740 0.8260 0.2803 0.9999 0.3673 0.8695 0.1934 0.2174 0.1740 0.0001 0.1740 0.0001 0.1934 0.2174 0.1934 " />
|
||||||
|
</IndexedFaceSet>
|
||||||
|
</Shape>
|
||||||
|
</Group>
|
||||||
|
</Transform>
|
||||||
|
</Transform>
|
||||||
|
</Scene>
|
||||||
|
</X3D>
|
||||||
|
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,16 @@
|
|||||||
|
.slider .thumb {
|
||||||
|
-fx-background-image: url("/visualiser/images/sun.png");
|
||||||
|
-fx-background-size: 25px;
|
||||||
|
-fx-pref-height: 25px;
|
||||||
|
-fx-pref-width: 25px;
|
||||||
|
-fx-background-position: top;
|
||||||
|
-fx-background-repeat: no-repeat;
|
||||||
|
-fx-focus-color: transparent;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider .track {
|
||||||
|
-fx-control-inner-background: dodgerblue;
|
||||||
|
-fx-border-color: rgba(30, 144, 255, 0.44);
|
||||||
|
-fx-border-radius: 0.25em, 0.25em, 0.166667em;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.image.Image?>
|
||||||
|
<?import javafx.scene.image.ImageView?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?import javafx.scene.layout.GridPane?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
|
<?import javafx.scene.layout.StackPane?>
|
||||||
|
|
||||||
|
<GridPane fx:id="arrowGridPane" alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.NextMarkController">
|
||||||
|
<children>
|
||||||
|
<Pane fx:id="pane2d" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="112.0" prefWidth="112.0">
|
||||||
|
<children>
|
||||||
|
<StackPane fx:id="arrowStackPane2d" prefHeight="112.0" prefWidth="112.0">
|
||||||
|
<children>
|
||||||
|
<ImageView fx:id="arrowImage" fitHeight="75.0" fitWidth="25.0">
|
||||||
|
<image>
|
||||||
|
<Image url="@../../images/nextMarkArrow2d.png" />
|
||||||
|
</image>
|
||||||
|
</ImageView>
|
||||||
|
</children>
|
||||||
|
</StackPane>
|
||||||
|
</children>
|
||||||
|
</Pane>
|
||||||
|
<Pane fx:id="pane3d" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="112.0" prefWidth="112.0">
|
||||||
|
<children>
|
||||||
|
<StackPane fx:id="arrowStackPane3d" prefHeight="112.0" prefWidth="112.0" />
|
||||||
|
</children>
|
||||||
|
</Pane>
|
||||||
|
</children>
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
|
||||||
|
</rowConstraints>
|
||||||
|
</GridPane>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,33 @@
|
|||||||
|
package network.MessageDecoders;
|
||||||
|
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
|
import network.MessageEncoders.RaceVisionByteEncoder;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the {@link network.Messages.BoatState} encoder and decoder.
|
||||||
|
*/
|
||||||
|
public class BoatStateDecoderTest {
|
||||||
|
private BoatState originalMessage;
|
||||||
|
private BoatState decodedMessage;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws InvalidMessageException {
|
||||||
|
originalMessage = new BoatState(0, 100);
|
||||||
|
|
||||||
|
byte[] encodedMessage = RaceVisionByteEncoder.encode(originalMessage);
|
||||||
|
BoatStateDecoder decoder = new BoatStateDecoder();
|
||||||
|
decoder.decode(encodedMessage);
|
||||||
|
decodedMessage = decoder.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decodingEqualsOriginal() {
|
||||||
|
assertEquals(originalMessage.getSourceID(), decodedMessage.getSourceID());
|
||||||
|
assertEquals(originalMessage.getBoatHealth(), decodedMessage.getBoatHealth());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue