diff --git a/src/main/java/seng302/gameServer/MessageFactory.java b/src/main/java/seng302/gameServer/MessageFactory.java index 03840c4c..b164dbf8 100644 --- a/src/main/java/seng302/gameServer/MessageFactory.java +++ b/src/main/java/seng302/gameServer/MessageFactory.java @@ -1,6 +1,5 @@ package seng302.gameServer; -import seng302.gameServer.messages.*; import java.util.ArrayList; import java.util.List; import seng302.gameServer.messages.BoatLocationMessage; @@ -25,9 +24,6 @@ import seng302.model.token.Token; import seng302.model.token.TokenType; import seng302.utilities.XMLGenerator; -import java.util.ArrayList; -import java.util.List; - /** * A Class for interfacing between the data we have in the GameState to the messages we need to send * through the MainServerThread. @@ -77,9 +73,6 @@ public class MessageFactory { } public static void updateBoats(List yachts) { -// for (ServerYacht serverYacht : yachts) { -// System.out.println(serverYacht); -// } xmlGenerator.getRace().setBoats(yachts); String xmlStr = xmlGenerator.getBoatsAsXml(); MessageFactory.boats = new XMLMessage(xmlStr, XMLMessageSubType.BOAT, xmlStr.length()); diff --git a/src/main/java/seng302/visualiser/ClientToServerThread.java b/src/main/java/seng302/visualiser/ClientToServerThread.java index b4840004..ceae1b09 100644 --- a/src/main/java/seng302/visualiser/ClientToServerThread.java +++ b/src/main/java/seng302/visualiser/ClientToServerThread.java @@ -1,14 +1,5 @@ package seng302.visualiser; -import javafx.application.Platform; -import javafx.util.Pair; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import seng302.gameServer.messages.*; -import seng302.model.stream.packets.PacketType; -import seng302.model.stream.packets.StreamPacket; -import seng302.utilities.XMLParser; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -43,7 +34,7 @@ import seng302.model.stream.xml.generator.RaceXMLTemplate; import seng302.model.stream.xml.generator.RegattaXMLTemplate; import seng302.utilities.XMLGenerator; import seng302.utilities.XMLParser; -import seng302.visualiser.controllers.ViewManager; + /** * A class describing a single connection to a Server for the purposes of sending and receiving on diff --git a/src/main/java/seng302/visualiser/GameView.java b/src/main/java/seng302/visualiser/GameView.java index db8a7686..37d579b7 100644 --- a/src/main/java/seng302/visualiser/GameView.java +++ b/src/main/java/seng302/visualiser/GameView.java @@ -1,13 +1,18 @@ package seng302.visualiser; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import javafx.scene.Group; import javafx.scene.Node; +import seng302.model.ClientYacht; import seng302.model.Limit; import seng302.model.ScaledPoint; import seng302.model.mark.CompoundMark; import seng302.model.mark.Corner; +import seng302.model.mark.Mark; +import seng302.utilities.Sounds; +import seng302.visualiser.fxObjects.Marker; /** * Abstract class for keeping functionality common between race visualisation. @@ -24,8 +29,36 @@ public abstract class GameView { List course = new ArrayList<>(); List compoundMarks = new ArrayList<>(); List courseOrder = new ArrayList<>(); + HashMap markerObjects = new HashMap<>(); public abstract Node getAssets(); public abstract void updateCourse(List newCourse, List sequence); public abstract void updateBorder(List border); + + void updateMarkArrows (ClientYacht yacht, int legNumber) { + CompoundMark compoundMark; + if (legNumber - 1 >= 0 && legNumber-1 < course.size()) { + Sounds.playMarkRoundingSound(); + compoundMark = course.get(legNumber-1); + for (Mark mark : compoundMark.getMarks()) { + markerObjects.get(mark).showNextExitArrow(); + } + } + CompoundMark nextMark = null; + if (legNumber < course.size()) { + Sounds.playMarkRoundingSound(); + nextMark = course.get(legNumber); + for (Mark mark : nextMark.getMarks()) { + markerObjects.get(mark).showNextEnterArrow(); + } + } + if (legNumber - 2 >= 0) { + CompoundMark lastMark = course.get(Math.max(0, legNumber - 2)); + if (lastMark != nextMark) { + for (Mark mark : lastMark.getMarks()) { + markerObjects.get(mark).hideAllArrows(); + } + } + } + } } diff --git a/src/main/java/seng302/visualiser/GameView3D.java b/src/main/java/seng302/visualiser/GameView3D.java index 29c12074..6851d2be 100644 --- a/src/main/java/seng302/visualiser/GameView3D.java +++ b/src/main/java/seng302/visualiser/GameView3D.java @@ -34,7 +34,6 @@ import seng302.model.mark.Corner; import seng302.model.mark.Mark; import seng302.model.token.Token; import seng302.utilities.GeoUtility; -import seng302.utilities.Sounds; import seng302.visualiser.cameras.ChaseCamera; import seng302.visualiser.cameras.IsometricCamera; import seng302.visualiser.cameras.RaceCamera; @@ -55,7 +54,7 @@ public class GameView3D extends GameView { private final double FOV = 60; private final double DEFAULT_CAMERA_X = 0; - private final double DEFAULT_CAMERA_Y = 100; + private final double DEFAULT_CAMERA_Y = 160; private Group root3D; private SubScene view; @@ -66,11 +65,6 @@ public class GameView3D extends GameView { private PerspectiveCamera isometricCam; private PerspectiveCamera topDownCam; private PerspectiveCamera chaseCam; - - /* Note that if either of these is null then values for it have not been added and the other - should be used as the limits of the map. */ - private Map markerObjects; - private BoatObject playerBoat; private Map boatObjects = new HashMap<>(); private Group wakesGroup = new Group(); @@ -535,31 +529,4 @@ public class GameView3D extends GameView { public void setWindDir(double windDir) { this.windDir = windDir; } - - private void updateMarkArrows (ClientYacht yacht, int legNumber) { - CompoundMark compoundMark; - if (legNumber - 1 >= 0) { - Sounds.playMarkRoundingSound(); - compoundMark = course.get(legNumber-1); - for (Mark mark : compoundMark.getMarks()) { - markerObjects.get(mark).showNextExitArrow(); - } - } - CompoundMark nextMark = null; - if (legNumber < course.size() - 1) { - Sounds.playMarkRoundingSound(); - nextMark = course.get(legNumber); - for (Mark mark : nextMark.getMarks()) { - markerObjects.get(mark).showNextEnterArrow(); - } - } - if (legNumber - 2 >= 0) { - CompoundMark lastMark = course.get(Math.max(0, legNumber - 2)); - if (lastMark != nextMark) { - for (Mark mark : lastMark.getMarks()) { - markerObjects.get(mark).hideAllArrows(); - } - } - } - } } \ No newline at end of file diff --git a/src/main/java/seng302/visualiser/MapMaker.java b/src/main/java/seng302/visualiser/MapMaker.java index 894b8e69..bc1e139b 100644 --- a/src/main/java/seng302/visualiser/MapMaker.java +++ b/src/main/java/seng302/visualiser/MapMaker.java @@ -108,10 +108,6 @@ public class MapMaker { return mapPreviews.get(index).getAssets(); } - public RaceXMLData getCurrentRace() { - return races.get(index); - } - public RegattaXMLData getCurrentRegatta() { return regattas.get(index); } diff --git a/src/main/java/seng302/visualiser/MapPreview.java b/src/main/java/seng302/visualiser/MapPreview.java index 4c2c3a38..9725e526 100644 --- a/src/main/java/seng302/visualiser/MapPreview.java +++ b/src/main/java/seng302/visualiser/MapPreview.java @@ -3,7 +3,6 @@ package seng302.visualiser; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Map; import javafx.application.Platform; import javafx.geometry.Point2D; import javafx.scene.Node; @@ -19,6 +18,7 @@ import seng302.model.mark.Corner; import seng302.model.mark.Mark; import seng302.utilities.GeoUtility; import seng302.visualiser.fxObjects.MarkArrowFactory; +import seng302.visualiser.fxObjects.Marker; import seng302.visualiser.fxObjects.assets_2D.CourseBoundary; import seng302.visualiser.fxObjects.assets_2D.Gate; import seng302.visualiser.fxObjects.assets_2D.Marker2D; @@ -29,7 +29,6 @@ import seng302.visualiser.fxObjects.assets_2D.Marker2D; public class MapPreview extends GameView { private Polygon raceBorder = new CourseBoundary(); - protected Map markerObjects; public MapPreview(List marks, List course, List border) { this.compoundMarks = marks; @@ -240,7 +239,7 @@ public class MapPreview extends GameView { * @param colour The desired colour of the gate. * @return the new gate. */ - private Gate makeAndBindGate(Marker2D m1, Marker2D m2, Paint colour) { + private Gate makeAndBindGate(Marker m1, Marker m2, Paint colour) { Gate gate = new Gate(colour); gate.startXProperty().bind( m1.layoutXProperty() diff --git a/src/main/java/seng302/visualiser/MiniMap.java b/src/main/java/seng302/visualiser/MiniMap.java index 8c9377dd..092f6c17 100644 --- a/src/main/java/seng302/visualiser/MiniMap.java +++ b/src/main/java/seng302/visualiser/MiniMap.java @@ -11,8 +11,6 @@ import seng302.model.ClientYacht; import seng302.model.Limit; import seng302.model.mark.CompoundMark; import seng302.model.mark.Corner; -import seng302.model.mark.Mark; -import seng302.utilities.Sounds; /** * Class converts a map preview to a minimap by adding boats. @@ -20,15 +18,9 @@ import seng302.utilities.Sounds; public class MiniMap extends MapPreview { private HashMap boatIcons = new HashMap<>(); - private Polygon playerBoat; - private double playerRotation; - private List boats; - private ClientYacht player; public MiniMap (List marks, List course, List border, List boats, ClientYacht player) { super(marks, course, border); - this.boats = boats; - this.player = player; setBoats(boats); player.addMarkRoundingListener(this::updateMarkArrows); } @@ -56,31 +48,4 @@ public class MiniMap extends MapPreview { gameObjects.getChildren().addAll(boatIcons.values()); }); } - - private void updateMarkArrows (ClientYacht yacht, int legNumber) { - CompoundMark compoundMark; - if (legNumber - 1 >= 0) { - Sounds.playMarkRoundingSound(); - compoundMark = course.get(legNumber-1); - for (Mark mark : compoundMark.getMarks()) { - markerObjects.get(mark).showNextExitArrow(); - } - } - CompoundMark nextMark = null; - if (legNumber < course.size() - 1) { - Sounds.playMarkRoundingSound(); - nextMark = course.get(legNumber); - for (Mark mark : nextMark.getMarks()) { - markerObjects.get(mark).showNextEnterArrow(); - } - } - if (legNumber - 2 >= 0) { - CompoundMark lastMark = course.get(Math.max(0, legNumber - 2)); - if (lastMark != nextMark) { - for (Mark mark : lastMark.getMarks()) { - markerObjects.get(mark).hideAllArrows(); - } - } - } - } } diff --git a/src/main/java/seng302/visualiser/ServerListener.java b/src/main/java/seng302/visualiser/ServerListener.java index b6c31141..32938edd 100644 --- a/src/main/java/seng302/visualiser/ServerListener.java +++ b/src/main/java/seng302/visualiser/ServerListener.java @@ -1,17 +1,17 @@ package seng302.visualiser; -import seng302.gameServer.ServerAdvertiser; -import seng302.gameServer.ServerDescription; +import static seng302.gameServer.ServerAdvertiser.getLocalHostIp; +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import javax.jmdns.JmDNS; import javax.jmdns.ServiceEvent; import javax.jmdns.ServiceListener; -import javax.jmdns.impl.JmDNSImpl; -import java.io.IOException; -import java.net.InetAddress; -import java.util.*; - -import static seng302.gameServer.ServerAdvertiser.getLocalHostIp; +import seng302.gameServer.ServerAdvertiser; +import seng302.gameServer.ServerDescription; /** * Listens for servers on the local network @@ -58,7 +58,7 @@ public class ServerListener{ servers.remove(toRemove); } - delegate.serverRemoved(new ArrayList(servers)); + delegate.serverRemoved(new ArrayList<>(servers)); // Get all other servers with the same name to respond if they are up jmdns.requestServiceInfo(ServerAdvertiser.SERVICE_TYPE, serverName); @@ -94,13 +94,6 @@ public class ServerListener{ listener = new GameServeMonitor(); jmdns.addServiceListener(ServerAdvertiser.SERVICE_TYPE, listener); - - /*new Timer().schedule(new TimerTask() { - @Override - public void run() { - refresh(); - } - }, 50, SERVICE_REFRESH_INTERVAL);*/ } public static ServerListener getInstance() throws IOException { @@ -134,7 +127,7 @@ public class ServerListener{ for (ServerDescription server : servers){ if (server.serverShouldBeRemoved()){ listener.servers.remove(server); - delegate.serverRemoved(new ArrayList(listener.servers)); + delegate.serverRemoved(new ArrayList<>(listener.servers)); } } diff --git a/src/main/java/seng302/visualiser/cameras/IsometricCamera.java b/src/main/java/seng302/visualiser/cameras/IsometricCamera.java index 85a0e502..2ba1bc8d 100644 --- a/src/main/java/seng302/visualiser/cameras/IsometricCamera.java +++ b/src/main/java/seng302/visualiser/cameras/IsometricCamera.java @@ -16,8 +16,8 @@ public class IsometricCamera extends PerspectiveCamera implements RaceCamera { private final Double MAX_Y = 170.0; private final Double PAN_LIMIT = 160.0; - private final Double NEAR_ZOOM_LIMIT = -50.0; - private final Double FAR_ZOOM_LIMIT = -160.0; + private final Double NEAR_ZOOM_LIMIT = -30.0; + private final Double FAR_ZOOM_LIMIT = -180.0; private Double horizontalPan; private Double verticalPan; @@ -29,7 +29,7 @@ public class IsometricCamera extends PerspectiveCamera implements RaceCamera { super(true); transforms = this.getTransforms(); - zoomFactor = (FAR_ZOOM_LIMIT + NEAR_ZOOM_LIMIT) / 2.0; + zoomFactor = FAR_ZOOM_LIMIT; horizontalPan = cameraStartX; verticalPan = cameraStartY; diff --git a/src/main/java/seng302/visualiser/cameras/TopDownCamera.java b/src/main/java/seng302/visualiser/cameras/TopDownCamera.java index 72d58707..d01decd4 100644 --- a/src/main/java/seng302/visualiser/cameras/TopDownCamera.java +++ b/src/main/java/seng302/visualiser/cameras/TopDownCamera.java @@ -11,9 +11,9 @@ import seng302.visualiser.fxObjects.assets_3D.BoatObject; public class TopDownCamera extends PerspectiveCamera implements RaceCamera { - private final Double PAN_LIMIT = 30.0; - private final Double NEAR_ZOOM_LIMIT = -30.0; - private final Double FAR_ZOOM_LIMIT = -130.0; + private final Double PAN_LIMIT = 40d; + private final Double NEAR_ZOOM_LIMIT = -20.0; + private final Double FAR_ZOOM_LIMIT = -145d; private final Double ZOOM_STEP = 2.5; private ObservableList transforms; diff --git a/src/main/java/seng302/visualiser/controllers/SplashScreenController.java b/src/main/java/seng302/visualiser/controllers/SplashScreenController.java index 68082869..5c392a6e 100644 --- a/src/main/java/seng302/visualiser/controllers/SplashScreenController.java +++ b/src/main/java/seng302/visualiser/controllers/SplashScreenController.java @@ -9,6 +9,7 @@ import javafx.scene.layout.StackPane; import javafx.stage.Stage; /** + * The pre loading screen before launch the start view * Created by Kusal on 26-Sep-17. */ public class SplashScreenController implements Initializable{ @@ -26,17 +27,14 @@ public class SplashScreenController implements Initializable{ public void run(){ try { Thread.sleep(3000); - Platform.runLater(new Runnable() { - @Override - public void run() { - try { - Stage stage = new Stage(); - ViewManager.getInstance().initialStartView(stage); - } catch (Exception e) { - e.printStackTrace(); - } - rootPane.getScene().getWindow().hide(); + Platform.runLater(() -> { + try { + Stage stage = new Stage(); + ViewManager.getInstance().initialStartView(stage); + } catch (Exception e) { + e.printStackTrace(); } + rootPane.getScene().getWindow().hide(); }); } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/main/java/seng302/visualiser/fxObjects/Marker.java b/src/main/java/seng302/visualiser/fxObjects/Marker.java new file mode 100644 index 00000000..53dcda32 --- /dev/null +++ b/src/main/java/seng302/visualiser/fxObjects/Marker.java @@ -0,0 +1,38 @@ +package seng302.visualiser.fxObjects; + +import java.util.ArrayList; +import java.util.List; +import javafx.scene.Group; +import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide; + +/** + * Created by cir27 on 28/09/17. + */ +public abstract class Marker extends Group{ + + protected List enterArrows = new ArrayList<>(); + protected List exitArrows = new ArrayList<>(); + protected int enterArrowIndex = 0; + protected int exitArrowIndex = 0; + + public abstract void addArrows(RoundingSide roundingSide, double entryAngle, double exitAngle); + /** + * Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows become hidden. + */ + public void showNextEnterArrow() { + showArrow(enterArrows, enterArrowIndex); + enterArrowIndex++; + } + + /** + * Shows the next ExitArrow. Does nothing if there are no more enter arrows. Other arrows become hidden. + */ + public void showNextExitArrow() { + showArrow(exitArrows, exitArrowIndex); + exitArrowIndex++; + } + + protected abstract void showArrow(List arrowList, int arrowListIndex); + + public abstract void hideAllArrows(); +} diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_2D/AnnotationBox.java b/src/main/java/seng302/visualiser/fxObjects/assets_2D/AnnotationBox.java deleted file mode 100644 index 994430e3..00000000 --- a/src/main/java/seng302/visualiser/fxObjects/assets_2D/AnnotationBox.java +++ /dev/null @@ -1,230 +0,0 @@ -package seng302.visualiser.fxObjects.assets_2D; - -import java.util.HashMap; -import java.util.Map; -import javafx.application.Platform; -import javafx.beans.value.ObservableValue; -import javafx.scene.CacheHint; -import javafx.scene.Group; -import javafx.scene.paint.Color; -import javafx.scene.paint.Paint; -import javafx.scene.shape.Rectangle; -import javafx.scene.text.Text; - -/** - * Grouping of string objects over a semi transparent background. - */ -public class AnnotationBox extends Group { - - @FunctionalInterface - public interface AnnotationFormatter { - String transformString (T input); - } - - /** - * Class stores a text object and relationship for updating the text object if needed - * - * @param The type of observable value passed to the annotation, if there is one. - */ - public class Annotation { - private Text text; - private ObservableValue source; - private AnnotationFormatter format; - - /** - * Constructor for observing annotation - * @param textObject the javaFX text object the annotation is displayed in - * @param source observable value that the annotation is taken from - * @param formatter interface describing how to format the source data if needed - */ - public Annotation (Text textObject, ObservableValue source, AnnotationFormatter formatter) { - this.text = textObject; - this.source = source; - this.format = formatter; - source.addListener((obs, oldVal, newVal) -> - Platform.runLater(() -> text.setText(format.transformString(newVal))) - ); - } - - /** - * Constructor for a static annotation - * @param textObject the javaFX text object the annotation is displayed in - * @param annotationText the static value of the test object - */ - public Annotation (Text textObject, String annotationText) { - textObject.setText(annotationText); - text = textObject; - } - - private Text getText () { - return text; - } - } - - //Text offset constants - private static final double X_OFFSET_TEXT = 20d; - private static final double Y_OFFSET_TEXT_INIT = -35d; - private static final double Y_OFFSET_PER_TEXT = 12d; - //Background constants - private static final double TEXT_BUFFER = 3; - private static final double BACKGROUND_X = X_OFFSET_TEXT - TEXT_BUFFER; - private static final double BACKGROUND_Y = Y_OFFSET_TEXT_INIT - TEXT_BUFFER; - private static final double BACKGROUND_H_PER_TEXT = 9.5d; - private static final double BACKGROUND_ARC_SIZE = 10; - - private int visibleAnnotations = 0; - private double backgroundWidth = 145d; - - private Rectangle background = new Rectangle(); - private Paint theme = Color.BLACK; - - private Map annotationsByName = new HashMap<>(); - - /** - * Creates an empty annotation box. The box is offset from (0,0) by (17, -38). - */ - public AnnotationBox() { - this.setCache(true); - background.setX(BACKGROUND_X); - background.setY(BACKGROUND_Y); - background.setWidth(backgroundWidth); - background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * 4); - background.setArcHeight(BACKGROUND_ARC_SIZE); - background.setArcWidth(BACKGROUND_ARC_SIZE); - background.setFill(new Color(1, 1, 1, 0.75)); - background.setStroke(theme); - background.setStrokeWidth(2); - background.setCache(true); - background.setCacheHint(CacheHint.SCALE); - this.getChildren().add(background); - } - - /** - * Adds an annotation to the box. Use the name to reference the annotation for removal or\ - * changing visibility. - * @param annotationName the name of the annotation. - * @param annotation the annotation. - */ - public void addAnnotation (String annotationName, Annotation annotation) { - annotationsByName.put(annotationName, annotation); - Platform.runLater(() -> { - this.getChildren().add(annotation.getText()); - visibleAnnotations++; - update(); - }); - } - - /** - * Adds an annotation with a constant text. - * @param annotationName The name of the annotation. Will be used to reference it later. - * @param annotationText The desired text. - */ - public void addAnnotation (String annotationName, String annotationText) { - Text text = getTextObject(); - addAnnotation(annotationName, new Annotation(text, annotationText)); - } - - /** - * Adds an annotation with the given name. The annotation will contain the value of the given - * ObservableValue. The formatter should return a String and takes an object of the same type as - * the ObservableValue as a parameter. The String is how you want the annotation to look. - * @param annotationName The annotation name. - * @param observable The observable value the annotation will display. - * @param formatter A formatting function for the observable value. - * @param The type of ObservableValue. - */ - public void addAnnotation (String annotationName, ObservableValue observable, - AnnotationFormatter formatter) { - Text newText = getTextObject(); - addAnnotation(annotationName, new Annotation<>(newText, observable, formatter)); - } - - /** - * Sets the visibility of the annotation with the given name if it exists. - * @param annotationName The name of the annotation - * @param visibility the desired visibility - */ - public void setAnnotationVisibility (String annotationName, boolean visibility) { - if (annotationsByName.containsKey(annotationName)) { - Text textField = annotationsByName.get(annotationName).text; - boolean currentState = textField.visibleProperty().get(); - if (visibility != currentState) { - if (visibility) - visibleAnnotations++; - else - visibleAnnotations--; - } - textField.setVisible(visibility); - update(); - } - } - - /** - * Removes the annotation with the given name if it exits. - * @param annotationName The name given when the annotation was created. - */ - public void removeAnnotation (String annotationName) { - if (annotationName.contains(annotationName)) { - Platform.runLater(() -> { - this.getChildren().remove(annotationsByName.remove(annotationName).getText()); - visibleAnnotations--; - update(); - }); - annotationsByName.remove(annotationName); - } - } - - /** - * Moves the annotation. - * @param x x location - * @param y y location - */ - public void setLocation (double x, double y) { - Platform.runLater(()-> this.relocate(x + BACKGROUND_X, y + BACKGROUND_Y)); - } - - /** - * Changes the width of the annotation box. Default is 145. - * @param width new width. - */ - public void setWidth (double width) { - backgroundWidth = width; - Platform.runLater(() -> background.setWidth(backgroundWidth)); - } - - private void update () { - background.setVisible(visibleAnnotations != 0); - background.setHeight(Math.abs(BACKGROUND_X) + TEXT_BUFFER + BACKGROUND_H_PER_TEXT * visibleAnnotations); - for (int i = 1; i <= visibleAnnotations; i++) { - Text text = (Text) this.getChildren().get(i); - if (text.visibleProperty().get()) { - text.setX(X_OFFSET_TEXT); - text.setY(Y_OFFSET_TEXT_INIT + Y_OFFSET_PER_TEXT * i); -// }); - } - } - } - - /** - * Returns a text object for an annotation. - * @return The text object - */ - private Text getTextObject() { - Text text = new Text(); - text.setFill(theme); - text.setStrokeWidth(2); -// text.setCacheHint(CacheHint.QUALITY); - text.setCache(true); - return text; - } - - /** - * Set the colour of the annotation box's border and text colour. - * @param value desired colour. - */ - public void setFill (Paint value) { - theme = value; - background.setStroke(theme); - annotationsByName.forEach((name, annotation) -> annotation.getText().setFill(theme)); - } -} diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_2D/Marker2D.java b/src/main/java/seng302/visualiser/fxObjects/assets_2D/Marker2D.java index d45b1341..e32023dc 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_2D/Marker2D.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_2D/Marker2D.java @@ -1,6 +1,5 @@ package seng302.visualiser.fxObjects.assets_2D; -import java.util.ArrayList; import java.util.List; import javafx.application.Platform; import javafx.scene.Group; @@ -8,18 +7,15 @@ import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import javafx.scene.shape.Circle; import seng302.visualiser.fxObjects.MarkArrowFactory; +import seng302.visualiser.fxObjects.Marker; /** * Visual object for a mark. Contains a coloured circle and any specified arrows. */ -public class Marker2D extends Group { +public class Marker2D extends Marker { private Circle mark = new Circle(); private Paint colour = Color.BLACK; - private List enterArrows = new ArrayList<>(); - private List exitArrows = new ArrayList<>(); - private int enterArrowIndex = 0; - private int exitArrowIndex = 0; /** * Creates a new Marker containing only a circle. The default colour is black. @@ -79,7 +75,8 @@ public class Marker2D extends Group { exitArrowIndex++; } - private void showArrow(List arrowList, int arrowListIndex) { + @Override + protected void showArrow(List arrowList, int arrowListIndex) { if (arrowListIndex < arrowList.size()) { Platform.runLater(() -> this.getChildren().setAll(mark, arrowList.get(arrowListIndex)) diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_2D/Wake.java b/src/main/java/seng302/visualiser/fxObjects/assets_2D/Wake.java index 58cd1718..0e164305 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_2D/Wake.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_2D/Wake.java @@ -16,10 +16,6 @@ public class Wake extends Group { //The number of wakes private int numWakes = 8; - //The total possible difference between the first wake and the last. Increasing/Decreasing this will make wakes fan out more/less. - private final double MAX_DIFF = 75; - //Increasing/decreasing this will alter the speed that wakes converge when the heading stop changing. Anything over about 1500 may cause oscillation. - private final int UNIFICATION_SPEED = 45; private Arc[] arcs = new Arc[numWakes]; @@ -69,34 +65,6 @@ public class Wake extends Group { rad += (14 / numWakes) + (velocity / 2.5); } }); -// } else { -// rotations[0] = rotation; -// ((Rotate) arcs[0].getTransforms().get(0)).setAngle(rotation); -// for (int i = 1; i < numWakes; i++) { -// double wakeSeparationRad = Math.toRadians(rotations[i - 1] - rotations[i]); -// double shortestDistance = Math.atan2( -// Math.sin(wakeSeparationRad), -// Math.cos(wakeSeparationRad) -// ); -// double distDeg = Math.toDegrees(shortestDistance); -// if (rotationalVelocities[i - 1] < 0.01 && rotationalVelocities[i - 1] > -0.01) { -// rotationalVelocities[i] = distDeg / UNIFICATION_SPEED * 2 * Math.log(Math.abs(distDeg) + 1) / Math.log(MAX_DIFF / numWakes); -// -// } else { -// if (distDeg < (MAX_DIFF / numWakes)) { -// rotationalVelocities[i] = distDeg / UNIFICATION_SPEED * Math.log(Math.abs(distDeg) + 1) / Math.log(MAX_DIFF / numWakes); -// } else -// rotationalVelocities[i] = rotationalVelocities[i - 1]; -// } -// } -// } - -// double rad = (14 / numWakes) + velocity; -// for (Arc arc : arcs) { -// arc.setRadiusX(rad); -// arc.setRadiusY(rad); -// rad += (14 / numWakes) + (velocity / 2.5); -// } } /** diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_2D/WindArrow.java b/src/main/java/seng302/visualiser/fxObjects/assets_2D/WindArrow.java deleted file mode 100644 index e77ced81..00000000 --- a/src/main/java/seng302/visualiser/fxObjects/assets_2D/WindArrow.java +++ /dev/null @@ -1,25 +0,0 @@ -package seng302.visualiser.fxObjects.assets_2D; - -import javafx.scene.paint.Paint; -import javafx.scene.shape.Polyline; -import javafx.scene.shape.StrokeLineCap; -import javafx.scene.shape.StrokeLineJoin; - -/** - * Created by cir27 on 5/09/17. - */ -public class WindArrow extends Polyline { - public WindArrow(Paint fill) { - this.getPoints().addAll( - -10d, 15d, - 0d, 25d, - 0d, -25d, - 0d, 25d, - 10d, 15d - ); - this.setStrokeLineCap(StrokeLineCap.ROUND); - this.setStroke(fill); - this.setStrokeWidth(5); - this.setStrokeLineJoin(StrokeLineJoin.ROUND); - } -} diff --git a/src/main/java/seng302/visualiser/fxObjects/assets_3D/Marker3D.java b/src/main/java/seng302/visualiser/fxObjects/assets_3D/Marker3D.java index 2766edfc..aa2420e1 100644 --- a/src/main/java/seng302/visualiser/fxObjects/assets_3D/Marker3D.java +++ b/src/main/java/seng302/visualiser/fxObjects/assets_3D/Marker3D.java @@ -1,22 +1,17 @@ package seng302.visualiser.fxObjects.assets_3D; - -import java.util.ArrayList; import java.util.List; import javafx.application.Platform; import javafx.scene.Group; import seng302.visualiser.fxObjects.MarkArrowFactory; import seng302.visualiser.fxObjects.MarkArrowFactory.RoundingSide; +import seng302.visualiser.fxObjects.Marker; /** * Visual object for a mark. Contains a coloured circle and any specified arrows. */ -public class Marker3D extends Group { +public class Marker3D extends Marker { private Model mark; - private List enterArrows = new ArrayList<>(); - private List exitArrows = new ArrayList<>(); - private int enterArrowIndex = 0; - private int exitArrowIndex = 0; private ModelType markType; private ModelType arrowType; @@ -60,23 +55,8 @@ public class Marker3D extends Group { ); } - /** - * Shows the next EnterArrow. Does nothing if there are no more enter arrows. Other arrows become hidden. - */ - public void showNextEnterArrow() { - showArrow(enterArrows, enterArrowIndex); - enterArrowIndex++; - } - - /** - * Shows the next ExitArrow. Does nothing if there are no more enter arrows. Other arrows become hidden. - */ - public void showNextExitArrow() { - showArrow(exitArrows, exitArrowIndex); - exitArrowIndex++; - } - - private void showArrow(List arrowList, int arrowListIndex) { + @Override + protected void showArrow(List arrowList, int arrowListIndex) { if (arrowListIndex < arrowList.size()) { Platform.runLater(() -> this.getChildren().setAll(mark.getAssets(), arrowList.get(arrowListIndex)) diff --git a/src/main/java/seng302/visualiser/map/Boundary.java b/src/main/java/seng302/visualiser/map/Boundary.java deleted file mode 100644 index 21f2661d..00000000 --- a/src/main/java/seng302/visualiser/map/Boundary.java +++ /dev/null @@ -1,44 +0,0 @@ -package seng302.visualiser.map; - -/** - * The Boundary class represents a rectangle territorial boundary on a map. It - * contains four extremity double values(N, E, S, W). N and S are represented as - * latitudes in radians. E and W are represented as longitudes in radians. - * - * Created by Haoming on 10/5/17 - */ -public class Boundary { - - private double northLat, eastLng, southLat, westLng; - - public Boundary(double northLat, double eastLng, double southLat, double westLng) { - this.northLat = northLat; - this.eastLng = eastLng; - this.southLat = southLat; - this.westLng = westLng; - } - - double getCentreLat() { - return (northLat + southLat) / 2; - } - - double getCentreLng() { - return (eastLng + westLng) / 2; - } - - double getNorthLat() { - return northLat; - } - - double getEastLng() { - return eastLng; - } - - double getSouthLat() { - return southLat; - } - - double getWestLng() { - return westLng; - } -} diff --git a/src/main/java/seng302/visualiser/map/CanvasMap.java b/src/main/java/seng302/visualiser/map/CanvasMap.java deleted file mode 100644 index e79805e4..00000000 --- a/src/main/java/seng302/visualiser/map/CanvasMap.java +++ /dev/null @@ -1,103 +0,0 @@ -package seng302.visualiser.map; - -import java.net.URL; -import javafx.geometry.Point2D; -import javafx.scene.image.Image; -import javax.net.ssl.HttpsURLConnection; -import seng302.model.GeoPoint; - -/** - * CanvasMap retrieves a map image with given geo boundary from Google Map server. - * By passing a rectangle like geo boundary, it returns a map image with the - * highest resolution. However, due to free quote account usage limit, the maximum - * resolution is only 1280 * 1280. - * - * Created by Haoming on 15/5/2017 - */ -public class CanvasMap { - - private Boundary boundary; - private long width, height; // desired image size - private int zoom; - - private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE"; - - public CanvasMap(Boundary boundary) { - this.boundary = boundary; - calculateOptimalMapSize(); - } - - public Image getMapImage() { - try { - URL url = new URL(getRequest()); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - - return new Image(connection.getInputStream()); - } catch (Exception e) { - System.out.println("[CanvasMap] Exception"); - return null; - } - } - - private String getRequest() { - StringBuilder sb = new StringBuilder(); - sb.append("https://maps.googleapis.com/maps/api/staticmap?"); - sb.append(String.format("center=%f,%f", boundary.getCentreLat(), boundary.getCentreLng())); - sb.append(String.format("&zoom=%d", zoom)); - sb.append(String.format("&size=%dx%d&scale=2", width, height)); - sb.append("&style=feature:all|element:labels|visibility:off"); // hide all labels on map -// sb.append(String.format("&markers=%f,%f", boundary.getSouthLat(), boundary.getWestLng())); -// sb.append(String.format("&key=%s", KEY)); - return sb.toString(); - } - - private void calculateOptimalMapSize() { - for (int z = 20; z > 0; z--) { - MapSize mapSize = getMapSize(z, boundary); - zoom = z; - width = mapSize.width; - height = mapSize.height; - // if map size is valid, exit the loop as we have the highest resolution - if (mapSize.isValid()) break; - } - } - - private MapSize getMapSize(int zoom, Boundary boundary) { - double scale = Math.pow(2, zoom); - GeoPoint geoSW = new GeoPoint(boundary.getSouthLat(), boundary.getWestLng()); - GeoPoint geoNE = new GeoPoint(boundary.getNorthLat(), boundary.getEastLng()); - Point2D pointSW = MercatorProjection.toMapPoint(geoSW); - Point2D pointNE = MercatorProjection.toMapPoint(geoNE); - return new MapSize(Math.abs(pointNE.getX() - pointSW.getX()) * scale, - Math.abs(pointNE.getY() - pointSW.getY()) * scale); - } - - class MapSize { - long width, height; - - MapSize(double width, double height) { - this.width = Math.round(width); - this.height = Math.round(height); - } - - /** - * Map size is valid when width and height are both less than 640 pixels - * @return true if both dimensions are less than 640px - */ - boolean isValid() { - return Math.max(width, height) <= 640; - } - } - - public long getWidth() { - return width; - } - - public long getHeight() { - return height; - } - - public int getZoom() { - return zoom; - } -} diff --git a/src/main/java/seng302/visualiser/map/MercatorProjection.java b/src/main/java/seng302/visualiser/map/MercatorProjection.java deleted file mode 100644 index 5a7f7741..00000000 --- a/src/main/java/seng302/visualiser/map/MercatorProjection.java +++ /dev/null @@ -1,55 +0,0 @@ -package seng302.visualiser.map; - -import javafx.geometry.Point2D; -import seng302.model.GeoPoint; - -/** - * An utility class useful to convert between Geo locations and Mercator projection - * planar coordinates. - * Created by Haoming on 15/5/2017 - */ -public class MercatorProjection { - - private static final double MERCATOR_RANGE = 256; - private static final double pixelsPerLngDegree = MERCATOR_RANGE / 360.0; - private static final double pixelsPerLngRadian = MERCATOR_RANGE / (2 * Math.PI); - - /** - * A help function keeps the value in bound between -0.9999 and 0.9999. - * @param value in bound value - * @return the value in bound - */ - private static double bound(double value) { - return Math.min(Math.max(value, -0.9999), 0.9999); - } - - /** - * Projects a Geo Location (lat, lng) on a planar - * @param geo GeoPoint (lat, lng) location to be projected - * @return the projection Point2D (x, y) on planar - */ - public static Point2D toMapPoint(GeoPoint geo) { - double x, y; - Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0); - x = (origin.getX() + geo.getLng() * pixelsPerLngDegree); - -// NOTE(appleton): Truncating to 0.9999 effectively limits latitude to -// 89.189. This is about a third of a tile past the edge of the world tile. - double sinY = bound(Math.sin(Math.toRadians(geo.getLat()))); - y = origin.getY() + 0.5 * Math.log((1 + sinY) / (1 - sinY)) * (-pixelsPerLngRadian); - return new Point2D(x, y); - } - - /** - * Converts the planar projection (x, y) back to Geo Location (lat, lng) - * @param point Point2D (x, y) to be converted back - * @return the original Geo location converted from the given projection point - */ - public static GeoPoint toMapGeo(Point2D point) { - Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0); - double lng = (point.getX() - origin.getX()) / pixelsPerLngDegree; - double latRadians = (point.getY() - origin.getY()) / (-pixelsPerLngRadian); - double lat = Math.toDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2.0); - return new GeoPoint(lat, lng); - } -} diff --git a/src/main/java/seng302/visualiser/map/TestMapController.java b/src/main/java/seng302/visualiser/map/TestMapController.java deleted file mode 100644 index cd0b4c60..00000000 --- a/src/main/java/seng302/visualiser/map/TestMapController.java +++ /dev/null @@ -1,22 +0,0 @@ -package seng302.visualiser.map; - -import java.net.URL; -import java.util.ResourceBundle; -import javafx.fxml.FXML; -import javafx.fxml.Initializable; -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; - -public class TestMapController implements Initializable{ - - @FXML - private Canvas mapCanvas; - - @Override - public void initialize(URL location, ResourceBundle resources) { - GraphicsContext gc = mapCanvas.getGraphicsContext2D(); - Boundary bound = new Boundary(57.662943, 11.848501, 57.673945, 11.824966); - CanvasMap canvasMap = new CanvasMap(bound); - gc.drawImage(canvasMap.getMapImage(), 0, 0, canvasMap.getWidth(), canvasMap.getHeight()); - } -} diff --git a/src/main/resources/meshes/mark_pointer.stl b/src/main/resources/meshes/mark_pointer.stl index be51d3f3..a7bc5099 100644 Binary files a/src/main/resources/meshes/mark_pointer.stl and b/src/main/resources/meshes/mark_pointer.stl differ diff --git a/src/main/resources/meshes/player_circle.stl b/src/main/resources/meshes/player_circle.stl index 5afc2bdd..b91cf5a2 100644 Binary files a/src/main/resources/meshes/player_circle.stl and b/src/main/resources/meshes/player_circle.stl differ diff --git a/src/test/java/seng302/visualiser/map/MercatorProjectionTest.java b/src/test/java/seng302/visualiser/map/MercatorProjectionTest.java deleted file mode 100644 index 03dcaccd..00000000 --- a/src/test/java/seng302/visualiser/map/MercatorProjectionTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package seng302.visualiser.map; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import seng302.model.GeoPoint; - -/** - * Unit test for Mercator Project class. - * Created by hyi25 on 15/05/17. - */ -public class MercatorProjectionTest { - @Test - public void toMapPoint() throws Exception { - GeoPoint geo1 = new GeoPoint(12.485394, 19.38947); - javafx.geometry.Point2D actualPoint1 = MercatorProjection.toMapPoint(geo1); - javafx.geometry.Point2D expectedPoint1 = new javafx.geometry.Point2D(141.78806755555556, 119.0503853635612); - assertEquals(expectedPoint1.getX(), actualPoint1.getX(), 0.0001); - assertEquals(expectedPoint1.getY(), actualPoint1.getY(), 0.0001); - - GeoPoint geo2 = new GeoPoint(77.456432, -23.456462); - javafx.geometry.Point2D actualPoint2 = MercatorProjection.toMapPoint(geo2); - javafx.geometry.Point2D expectedPoint2 = new javafx.geometry.Point2D(111.31984924444444, 38.03143323746788); - assertEquals(expectedPoint2.getX(), actualPoint2.getX(), 0.0001); - assertEquals(expectedPoint2.getY(), actualPoint2.getY(), 0.0001); - } - - @Test - public void toMapGeo() throws Exception { - javafx.geometry.Point2D point1 = new javafx.geometry.Point2D(123.1234, 25.4565); - GeoPoint actualGeo1 = MercatorProjection.toMapGeo(point1); - GeoPoint expectedGeo1 = new GeoPoint(80.77043127275441, -6.857718749999995); - assertEquals(expectedGeo1.getLat(), actualGeo1.getLat(), 0.0001); - assertEquals(expectedGeo1.getLng(), actualGeo1.getLng(), 0.0001); - - javafx.geometry.Point2D point2 = new javafx.geometry.Point2D(1.235, 255.4565); - GeoPoint actualGeo2 = MercatorProjection.toMapGeo(point2); - GeoPoint expectedGeo2 = new GeoPoint(-84.98475532898011, -178.26328125); - assertEquals(expectedGeo2.getLat(), actualGeo2.getLat(), 0.0001); - assertEquals(expectedGeo2.getLng(), actualGeo2.getLng(), 0.0001); - } - -} \ No newline at end of file