From 64e96a1b8b935598464de5b668f5211399f8b0da Mon Sep 17 00:00:00 2001 From: Joseph Gardner Date: Tue, 29 Aug 2017 12:14:28 +1200 Subject: [PATCH 01/51] Class for shifting wind. #story[1187] --- .../src/main/java/mock/app/Event.java | 10 +--- .../src/main/java/mock/model/MockRace.java | 5 +- .../{ => wind}/ConstantWindGenerator.java | 4 +- .../model/{ => wind}/RandomWindGenerator.java | 2 +- .../model/wind/ShiftingWindGenerator.java | 51 +++++++++++++++++++ .../mock/model/{ => wind}/WindGenerator.java | 2 +- .../mock/model/ConstantWindGeneratorTest.java | 2 + .../test/java/mock/model/MockRaceTest.java | 5 +- .../mock/model/RandomWindGeneratorTest.java | 1 + 9 files changed, 62 insertions(+), 20 deletions(-) rename racevisionGame/src/main/java/mock/model/{ => wind}/ConstantWindGenerator.java (96%) rename racevisionGame/src/main/java/mock/model/{ => wind}/RandomWindGenerator.java (99%) create mode 100644 racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java rename racevisionGame/src/main/java/mock/model/{ => wind}/WindGenerator.java (96%) diff --git a/racevisionGame/src/main/java/mock/app/Event.java b/racevisionGame/src/main/java/mock/app/Event.java index 228534c2..f36ac714 100644 --- a/racevisionGame/src/main/java/mock/app/Event.java +++ b/racevisionGame/src/main/java/mock/app/Event.java @@ -4,6 +4,8 @@ import mock.dataInput.PolarParser; import mock.exceptions.EventConstructionException; import mock.model.*; import mock.model.commandFactory.CompositeCommand; +import mock.model.wind.RandomWindGenerator; +import mock.model.wind.WindGenerator; import mock.xml.RaceXMLCreator; import network.Messages.LatestMessages; import org.xml.sax.SAXException; @@ -18,16 +20,8 @@ import shared.model.Constants; import javax.xml.bind.JAXBException; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; import java.io.IOException; -import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; -import java.time.Duration; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; /** diff --git a/racevisionGame/src/main/java/mock/model/MockRace.java b/racevisionGame/src/main/java/mock/model/MockRace.java index 379123af..ed7b6fd2 100644 --- a/racevisionGame/src/main/java/mock/model/MockRace.java +++ b/racevisionGame/src/main/java/mock/model/MockRace.java @@ -1,9 +1,6 @@ package mock.model; -import javafx.animation.AnimationTimer; -import mock.xml.*; -import network.Messages.BoatLocation; -import network.Messages.BoatStatus; +import mock.model.wind.WindGenerator; import network.Messages.Enums.BoatStatusEnum; import network.Messages.Enums.RaceStatusEnum; import shared.dataInput.BoatDataSource; diff --git a/racevisionGame/src/main/java/mock/model/ConstantWindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/ConstantWindGenerator.java similarity index 96% rename from racevisionGame/src/main/java/mock/model/ConstantWindGenerator.java rename to racevisionGame/src/main/java/mock/model/wind/ConstantWindGenerator.java index ae14daac..6cdfafe9 100644 --- a/racevisionGame/src/main/java/mock/model/ConstantWindGenerator.java +++ b/racevisionGame/src/main/java/mock/model/wind/ConstantWindGenerator.java @@ -1,11 +1,9 @@ -package mock.model; +package mock.model.wind; import shared.model.Bearing; import shared.model.Wind; -import java.util.Random; - /** * This class generates Wind objects for use in a MockRace. * Initialised with a baseline wind speed and direction, and keeps it constant. diff --git a/racevisionGame/src/main/java/mock/model/RandomWindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/RandomWindGenerator.java similarity index 99% rename from racevisionGame/src/main/java/mock/model/RandomWindGenerator.java rename to racevisionGame/src/main/java/mock/model/wind/RandomWindGenerator.java index 4f981b8d..bd7b13c3 100644 --- a/racevisionGame/src/main/java/mock/model/RandomWindGenerator.java +++ b/racevisionGame/src/main/java/mock/model/wind/RandomWindGenerator.java @@ -1,4 +1,4 @@ -package mock.model; +package mock.model.wind; import shared.model.Bearing; diff --git a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java new file mode 100644 index 00000000..4a1c158e --- /dev/null +++ b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java @@ -0,0 +1,51 @@ +package mock.model.wind; + +import shared.model.Bearing; +import shared.model.Wind; + +/** + * Created by jjg64 on 28/08/17. + */ +public class ShiftingWindGenerator implements WindGenerator { + Bearing baselineBearing; + double baseLineSpeed; + double maxBearingVariance = 5; // In degrees + double oscillationPeriod = 3e6; // In milliseconds + + public ShiftingWindGenerator(Bearing baselineBearing, double baseLineSpeed) { + this.baselineBearing = baselineBearing; + this.baseLineSpeed = baseLineSpeed; + } + + @Override + public Wind generateBaselineWind() { + return new Wind(baselineBearing, baseLineSpeed); + } + + @Override + public Wind generateNextWind(Wind currentWind) { + return changeWind(currentWind); + } + + private Wind changeWind(Wind currentWind) { + currentWind = oscillateWind(currentWind); + currentWind = shiftWind(currentWind); + return currentWind; + } + + private Wind oscillateWind(Wind currentWind) { + return currentWind; + } + + private Wind shiftWind(Wind currentWind) { + return currentWind; + } + + public void setMaxBearingVariance(double maxBearingVariance) { + this.maxBearingVariance = maxBearingVariance; + } + + public void setOscillationPeriod(double oscillationPeriod) { + this.oscillationPeriod = oscillationPeriod; + } +} diff --git a/racevisionGame/src/main/java/mock/model/WindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/WindGenerator.java similarity index 96% rename from racevisionGame/src/main/java/mock/model/WindGenerator.java rename to racevisionGame/src/main/java/mock/model/wind/WindGenerator.java index 8285d5d3..52ee2cd6 100644 --- a/racevisionGame/src/main/java/mock/model/WindGenerator.java +++ b/racevisionGame/src/main/java/mock/model/wind/WindGenerator.java @@ -1,4 +1,4 @@ -package mock.model; +package mock.model.wind; import shared.model.Wind; diff --git a/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java b/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java index 6f67dc30..f7c69acf 100644 --- a/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java +++ b/racevisionGame/src/test/java/mock/model/ConstantWindGeneratorTest.java @@ -1,5 +1,7 @@ package mock.model; +import mock.model.wind.ConstantWindGenerator; +import mock.model.wind.WindGenerator; import org.junit.Before; import org.junit.Test; import shared.model.Bearing; diff --git a/racevisionGame/src/test/java/mock/model/MockRaceTest.java b/racevisionGame/src/test/java/mock/model/MockRaceTest.java index 4f3f7705..f53b2970 100644 --- a/racevisionGame/src/test/java/mock/model/MockRaceTest.java +++ b/racevisionGame/src/test/java/mock/model/MockRaceTest.java @@ -1,7 +1,8 @@ package mock.model; import mock.dataInput.PolarParserTest; -import network.Messages.LatestMessages; +import mock.model.wind.ConstantWindGenerator; +import mock.model.wind.WindGenerator; import shared.dataInput.*; import shared.exceptions.InvalidBoatDataException; import shared.exceptions.InvalidRaceDataException; @@ -9,8 +10,6 @@ import shared.exceptions.InvalidRegattaDataException; import shared.model.Bearing; import shared.model.Constants; -import static org.junit.Assert.*; - public class MockRaceTest { //TODO diff --git a/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java b/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java index 76eed977..0f60bcea 100644 --- a/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java +++ b/racevisionGame/src/test/java/mock/model/RandomWindGeneratorTest.java @@ -1,5 +1,6 @@ package mock.model; +import mock.model.wind.RandomWindGenerator; import org.junit.Before; import org.junit.Test; import shared.model.Bearing; From 12e2ae9c0150ad6e3e5de6ca77ff606cb11fcbf8 Mon Sep 17 00:00:00 2001 From: Joseph Gardner Date: Tue, 29 Aug 2017 13:21:34 +1200 Subject: [PATCH 02/51] Started implementing wind oscillation. #story[1187] --- .../src/main/java/mock/app/Event.java | 17 ++++--- .../model/wind/ShiftingWindGenerator.java | 49 ++++++++++++++----- .../src/main/java/shared/model/Wind.java | 7 +++ 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/racevisionGame/src/main/java/mock/app/Event.java b/racevisionGame/src/main/java/mock/app/Event.java index f36ac714..096705bb 100644 --- a/racevisionGame/src/main/java/mock/app/Event.java +++ b/racevisionGame/src/main/java/mock/app/Event.java @@ -5,6 +5,7 @@ import mock.exceptions.EventConstructionException; import mock.model.*; import mock.model.commandFactory.CompositeCommand; import mock.model.wind.RandomWindGenerator; +import mock.model.wind.ShiftingWindGenerator; import mock.model.wind.WindGenerator; import mock.xml.RaceXMLCreator; import network.Messages.LatestMessages; @@ -124,13 +125,17 @@ public class Event { this.latestMessages = new LatestMessages(); //Create and start race. - WindGenerator windGenerator = new RandomWindGenerator( +// WindGenerator windGenerator = new RandomWindGenerator( +// Bearing.fromDegrees(225), +// Bearing.fromDegrees(215), +// Bearing.fromDegrees(235), +// 12d, +// 8d, +// 16d ); + WindGenerator windGenerator = new ShiftingWindGenerator( Bearing.fromDegrees(225), - Bearing.fromDegrees(215), - Bearing.fromDegrees(235), - 12d, - 8d, - 16d ); + 12 + ); RaceLogic newRace = new RaceLogic( new MockRace( boatDataSource, diff --git a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java index 4a1c158e..fc3e3dc2 100644 --- a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java +++ b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java @@ -3,18 +3,28 @@ package mock.model.wind; import shared.model.Bearing; import shared.model.Wind; +import java.util.Random; + /** * Created by jjg64 on 28/08/17. */ public class ShiftingWindGenerator implements WindGenerator { Bearing baselineBearing; double baseLineSpeed; - double maxBearingVariance = 5; // In degrees + double speedVariance = 4; + double bearingVariance = 5; // In degrees double oscillationPeriod = 3e6; // In milliseconds + double timeOfLastOscillationReset = 0; + double timeSinceLastChange = 0; + double timeSinceLastShift = 0; // Back / veer + + boolean oscillationLeft = false; + public ShiftingWindGenerator(Bearing baselineBearing, double baseLineSpeed) { this.baselineBearing = baselineBearing; this.baseLineSpeed = baseLineSpeed; + initialiseOscillationDirection(); } @Override @@ -27,22 +37,39 @@ public class ShiftingWindGenerator implements WindGenerator { return changeWind(currentWind); } - private Wind changeWind(Wind currentWind) { - currentWind = oscillateWind(currentWind); - currentWind = shiftWind(currentWind); - return currentWind; + private Wind changeWind(Wind wind) { + Wind newWind = new Wind(wind.getWindDirection(), wind.getWindSpeed()); + oscillateWind(newWind); + shiftWind(newWind); + changeWindSpeed(newWind); + return newWind; + } + + private void oscillateWind(Wind wind) { + double timeSinceLastOscillationReset = System.currentTimeMillis() - timeOfLastOscillationReset; + if (oscillationLeft) { + + } + } + + private void shiftWind(Wind wind) { + } + + private void changeWindSpeed(Wind wind) { + } - private Wind oscillateWind(Wind currentWind) { - return currentWind; + private void initialiseOscillationDirection() { + oscillationLeft = new Random().nextBoolean(); + timeOfLastOscillationReset = System.currentTimeMillis(); } - private Wind shiftWind(Wind currentWind) { - return currentWind; + public void setBearingVariance(double maxBearingVariance) { + this.bearingVariance = maxBearingVariance; } - public void setMaxBearingVariance(double maxBearingVariance) { - this.maxBearingVariance = maxBearingVariance; + public void setSpeedVariance(double speedVariance) { + this.speedVariance = speedVariance; } public void setOscillationPeriod(double oscillationPeriod) { diff --git a/racevisionGame/src/main/java/shared/model/Wind.java b/racevisionGame/src/main/java/shared/model/Wind.java index 08d391c2..531d8473 100644 --- a/racevisionGame/src/main/java/shared/model/Wind.java +++ b/racevisionGame/src/main/java/shared/model/Wind.java @@ -48,4 +48,11 @@ public class Wind { return windSpeed; } + public void setWindSpeed(double windSpeed) { + this.windSpeed = windSpeed; + } + + public void setWindDirection(Bearing windDirection) { + this.windDirection = windDirection; + } } From d0ba7b93e09187be12f07df2b5a8facc852888fc Mon Sep 17 00:00:00 2001 From: Joseph Gardner Date: Tue, 29 Aug 2017 14:40:52 +1200 Subject: [PATCH 03/51] Wind oscillates, replaces random wind with shifting wind. #story[1187] --- .../src/main/java/mock/app/Event.java | 2 ++ .../model/wind/ShiftingWindGenerator.java | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/racevisionGame/src/main/java/mock/app/Event.java b/racevisionGame/src/main/java/mock/app/Event.java index d75307cf..c7f7d5ff 100644 --- a/racevisionGame/src/main/java/mock/app/Event.java +++ b/racevisionGame/src/main/java/mock/app/Event.java @@ -23,6 +23,8 @@ import javax.xml.bind.JAXBException; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; /** diff --git a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java index fc3e3dc2..cb94e55c 100644 --- a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java +++ b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java @@ -13,10 +13,11 @@ public class ShiftingWindGenerator implements WindGenerator { double baseLineSpeed; double speedVariance = 4; double bearingVariance = 5; // In degrees - double oscillationPeriod = 3e6; // In milliseconds + double oscillationVariance = 0.25; + double oscillationPeriod = 1e3 * 60 * 1; // In milliseconds double timeOfLastOscillationReset = 0; - double timeSinceLastChange = 0; + double timeOfLastChange = 0; double timeSinceLastShift = 0; // Back / veer boolean oscillationLeft = false; @@ -42,13 +43,39 @@ public class ShiftingWindGenerator implements WindGenerator { oscillateWind(newWind); shiftWind(newWind); changeWindSpeed(newWind); + timeOfLastChange = System.currentTimeMillis(); return newWind; } private void oscillateWind(Wind wind) { double timeSinceLastOscillationReset = System.currentTimeMillis() - timeOfLastOscillationReset; + double timeSinceLastChange = System.currentTimeMillis() - timeOfLastChange; + double newBearing = wind.getWindDirection().degrees(); + double degreeChange = timeSinceLastChange * 2 * bearingVariance / oscillationPeriod; + degreeChange = (1 - oscillationVariance) * degreeChange + (2 * oscillationVariance) * degreeChange * Math.random(); + + if (timeSinceLastOscillationReset >= oscillationPeriod) { + timeOfLastOscillationReset = System.currentTimeMillis(); + oscillationLeft = !oscillationLeft; + } if (oscillationLeft) { - + newBearing -= degreeChange; + if (newBearing < baselineBearing.degrees() - bearingVariance) { + System.out.println(timeSinceLastOscillationReset); + oscillationLeft = !oscillationLeft; + timeOfLastOscillationReset = System.currentTimeMillis(); + } else { + wind.setWindDirection(Bearing.fromDegrees(newBearing % 360)); + } + } else { + newBearing += degreeChange; + if (newBearing > baselineBearing.degrees() + bearingVariance) { + System.out.println(timeSinceLastOscillationReset); + oscillationLeft = !oscillationLeft; + timeOfLastOscillationReset = System.currentTimeMillis(); + } else { + wind.setWindDirection(Bearing.fromDegrees(newBearing % 360)); + } } } From b0f7c5e73475f18a13e085c7aa726b15b26d4b2d Mon Sep 17 00:00:00 2001 From: Joseph Gardner Date: Tue, 29 Aug 2017 15:53:41 +1200 Subject: [PATCH 04/51] Wind speed changes depending on where the wind direction is. #story[1187] --- .../model/wind/ShiftingWindGenerator.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java index cb94e55c..f9e5a4be 100644 --- a/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java +++ b/racevisionGame/src/main/java/mock/model/wind/ShiftingWindGenerator.java @@ -11,7 +11,7 @@ import java.util.Random; public class ShiftingWindGenerator implements WindGenerator { Bearing baselineBearing; double baseLineSpeed; - double speedVariance = 4; + double speedVariance = 2; double bearingVariance = 5; // In degrees double oscillationVariance = 0.25; double oscillationPeriod = 1e3 * 60 * 1; // In milliseconds @@ -20,7 +20,7 @@ public class ShiftingWindGenerator implements WindGenerator { double timeOfLastChange = 0; double timeSinceLastShift = 0; // Back / veer - boolean oscillationLeft = false; + boolean anticlockwise = false; public ShiftingWindGenerator(Bearing baselineBearing, double baseLineSpeed) { this.baselineBearing = baselineBearing; @@ -56,13 +56,13 @@ public class ShiftingWindGenerator implements WindGenerator { if (timeSinceLastOscillationReset >= oscillationPeriod) { timeOfLastOscillationReset = System.currentTimeMillis(); - oscillationLeft = !oscillationLeft; + anticlockwise = !anticlockwise; } - if (oscillationLeft) { + if (anticlockwise) { newBearing -= degreeChange; if (newBearing < baselineBearing.degrees() - bearingVariance) { System.out.println(timeSinceLastOscillationReset); - oscillationLeft = !oscillationLeft; + anticlockwise = !anticlockwise; timeOfLastOscillationReset = System.currentTimeMillis(); } else { wind.setWindDirection(Bearing.fromDegrees(newBearing % 360)); @@ -71,7 +71,7 @@ public class ShiftingWindGenerator implements WindGenerator { newBearing += degreeChange; if (newBearing > baselineBearing.degrees() + bearingVariance) { System.out.println(timeSinceLastOscillationReset); - oscillationLeft = !oscillationLeft; + anticlockwise = !anticlockwise; timeOfLastOscillationReset = System.currentTimeMillis(); } else { wind.setWindDirection(Bearing.fromDegrees(newBearing % 360)); @@ -83,11 +83,14 @@ public class ShiftingWindGenerator implements WindGenerator { } private void changeWindSpeed(Wind wind) { - + double deg = wind.getWindDirection().degrees(); + double offset = deg - baselineBearing.degrees(); + double newSpeed = offset / bearingVariance * speedVariance + baseLineSpeed; + wind.setWindSpeed(newSpeed); } private void initialiseOscillationDirection() { - oscillationLeft = new Random().nextBoolean(); + anticlockwise = new Random().nextBoolean(); timeOfLastOscillationReset = System.currentTimeMillis(); } From 0927e62ea36d13a4d9fa0cd536a30b2a68814e52 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Wed, 30 Aug 2017 12:46:05 +1200 Subject: [PATCH 05/51] Changed dependency to see if it will pass the CI runner #story[1191] --- racevisionGame/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/racevisionGame/pom.xml b/racevisionGame/pom.xml index 16afe756..20282320 100644 --- a/racevisionGame/pom.xml +++ b/racevisionGame/pom.xml @@ -55,8 +55,8 @@ - InteractiveMesh - STLImporter + JavaInteractiveMesh + ModelImporters 0_4_1 @@ -79,7 +79,7 @@ interactivemesh - Interactive Mesh + Interactive Mesh http://umbrasheep.com:8888/repository/internal/ From 921e0999b8373d6c65d43f44e9fc3839d126c140 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Wed, 30 Aug 2017 13:01:37 +1200 Subject: [PATCH 06/51] Testing if dependency for stl works this time #story[1191] --- racevisionGame/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/racevisionGame/pom.xml b/racevisionGame/pom.xml index 20282320..f154cf77 100644 --- a/racevisionGame/pom.xml +++ b/racevisionGame/pom.xml @@ -56,8 +56,8 @@ JavaInteractiveMesh - ModelImporters - 0_4_1 + STLImporter + 0.7 From 4910d2712cb0c8d1be6196cbb2188678e87db481 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Wed, 30 Aug 2017 13:56:57 +1200 Subject: [PATCH 07/51] Changed STL Importers Version #story[1191] --- racevisionGame/pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/racevisionGame/pom.xml b/racevisionGame/pom.xml index f154cf77..4a3c65a4 100644 --- a/racevisionGame/pom.xml +++ b/racevisionGame/pom.xml @@ -46,8 +46,6 @@ 15.0 - - org.geotools gt-referencing From e7164d8a78668c73ffa417dc0d24942215936a29 Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Wed, 30 Aug 2017 13:57:15 +1200 Subject: [PATCH 08/51] View3D perspective camera is now operational #story[1196] --- .../Controllers/HostController.java | 3 +- .../main/java/visualiser/model/View3D.java | 54 +++++++++---------- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index a085041b..9293d1f0 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -7,6 +7,7 @@ import javafx.scene.control.SplitPane; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; +import javafx.scene.shape.Box; import mock.app.Event; import mock.exceptions.EventConstructionException; import visualiser.model.View3D; @@ -57,7 +58,7 @@ public class HostController extends Controller { public void initialize(URL location, ResourceBundle resources) { fancyStuff = new View3D(); playerContainer.add(fancyStuff, 0,0); - fancyStuff.spinBox(); + fancyStuff.addShape(new Box(100,100,100)); } /** diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/model/View3D.java index f6937755..42674c33 100644 --- a/racevisionGame/src/main/java/visualiser/model/View3D.java +++ b/racevisionGame/src/main/java/visualiser/model/View3D.java @@ -1,49 +1,43 @@ package visualiser.model; -import javafx.animation.AnimationTimer; import javafx.scene.Group; import javafx.scene.PerspectiveCamera; import javafx.scene.SubScene; import javafx.scene.layout.Pane; -import javafx.scene.shape.Box; -import javafx.scene.shape.CullFace; -import javafx.scene.transform.Rotate; +import javafx.scene.paint.Color; +import javafx.scene.shape.Shape3D; + +import java.util.ArrayList; +import java.util.List; /** * Created by connortaylorbrown on 30/08/17. */ public class View3D extends Pane { SubScene scene; - PerspectiveCamera camera; - Box box; + Group world; + List shapes; public View3D() { - scene = new SubScene(this, 500, 500); - camera = new PerspectiveCamera(); + shapes = new ArrayList<>(); + world = new Group(); + + scene = new SubScene(world, 300, 300); + scene.widthProperty().bind(this.widthProperty()); + scene.heightProperty().bind(this.heightProperty()); + scene.setFill(Color.BLACK); + + PerspectiveCamera camera = new PerspectiveCamera(true); + camera.setNearClip(0.1); + camera.setFarClip(1000.0); + camera.setTranslateZ(-500); scene.setCamera(camera); - } - - public void spinBox() { - camera.getTransforms().add(new Rotate(-20, Rotate.X_AXIS)); - - box = new Box(50,50,50); - box.setTranslateX(100); - box.setTranslateY(100); - box.setCullFace(CullFace.BACK); - Rotate ry = new Rotate(0, 0,0,0, Rotate.Y_AXIS); - box.getTransforms().add(ry); - - this.getChildren().add(camera); - this.getChildren().add(box); - - AnimationTimer rotation = new AnimationTimer() { - @Override - public void handle(long now) { - ry.setAngle(ry.getAngle() + 0.1); - } - }; + this.getChildren().add(scene); + } - rotation.start(); + public void addShape(Shape3D shape) { + shapes.add(shape); + world.getChildren().add(shape); } } From bb7eb7cb44bb3cef7d11b6e6a81cfec1e9c1fe46 Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Wed, 30 Aug 2017 15:05:08 +1200 Subject: [PATCH 09/51] Added adapter interface for PerspectiveCamera frustum and transformations in View3D. - Tested interface while initialising HostController #story[1196] --- .../Controllers/HostController.java | 13 +- .../main/java/visualiser/model/View3D.java | 111 ++++++++++++++++-- 2 files changed, 110 insertions(+), 14 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 9293d1f0..6d11e65e 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -52,13 +52,18 @@ public class HostController extends Controller { private Event game; - private View3D fancyStuff; + private View3D view3D; @Override public void initialize(URL location, ResourceBundle resources) { - fancyStuff = new View3D(); - playerContainer.add(fancyStuff, 0,0); - fancyStuff.addShape(new Box(100,100,100)); + view3D = new View3D(); + playerContainer.add(view3D, 0,0); + + Box box = new Box(100, 100, 100); + view3D.addShape(box); + view3D.setPivot(box); + view3D.setDistance(500); + view3D.setPitch(20); } /** diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/model/View3D.java index 42674c33..9748fc8f 100644 --- a/racevisionGame/src/main/java/visualiser/model/View3D.java +++ b/racevisionGame/src/main/java/visualiser/model/View3D.java @@ -6,38 +6,129 @@ import javafx.scene.SubScene; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Shape3D; +import javafx.scene.transform.Rotate; +import javafx.scene.transform.Translate; import java.util.ArrayList; import java.util.List; /** - * Created by connortaylorbrown on 30/08/17. + * Control for rendering 3D objects visible through a PerspectiveCamera. Implements Adapter Pattern to + * interface with camera, and allows clients to add shapes to the scene. All scenes contain sea plane and + * sky box, whose textures are set with special methods. */ public class View3D extends Pane { - SubScene scene; - Group world; - List shapes; + private Group world; + private List shapes; + private double nearClip; + private double farClip; + + /** + * Position camera pivots around + */ + private Translate pivot; + /** + * Distance of camera from pivot point + */ + private Translate distance; + /** + * Angle along ground between z-axis and camera + */ + private Rotate yaw; + /** + * Angle between ground plane and camera direction + */ + private Rotate pitch; + + /** + * Default constructor for View3D. Sets up Scene and PerspectiveCamera. + */ public View3D() { shapes = new ArrayList<>(); world = new Group(); - scene = new SubScene(world, 300, 300); + SubScene scene = new SubScene(world, 300, 300); scene.widthProperty().bind(this.widthProperty()); scene.heightProperty().bind(this.heightProperty()); scene.setFill(Color.BLACK); - PerspectiveCamera camera = new PerspectiveCamera(true); - camera.setNearClip(0.1); - camera.setFarClip(1000.0); - camera.setTranslateZ(-500); - scene.setCamera(camera); + scene.setCamera(buildCamera()); this.getChildren().add(scene); } + /** + * Sets up camera view frustum and binds transformations + * @return perspective camera + */ + private PerspectiveCamera buildCamera() { + PerspectiveCamera camera = new PerspectiveCamera(true); + + // Set up view frustum + nearClip = 0.1; + farClip = 1000.0; + camera.setNearClip(nearClip); + camera.setFarClip(farClip); + + // Set up transformations + pivot = new Translate(); + distance = new Translate(); + yaw = new Rotate(0, Rotate.Y_AXIS); + pitch = new Rotate(0, Rotate.X_AXIS); + camera.getTransforms().addAll(pivot, yaw, pitch, distance); + + return camera; + } + + /** + * Adds new Shape3D object to scene + * @param shape to add + */ public void addShape(Shape3D shape) { shapes.add(shape); world.getChildren().add(shape); } + + public void setNearClip(double nearClip) { + this.nearClip = nearClip; + } + + public void setFarClip(double farClip) { + this.farClip = farClip; + } + + /** + * Set object to centre on camera + * @param pivot centred object + */ + public void setPivot(Shape3D pivot) { + this.pivot.setX(pivot.getTranslateX()); + this.pivot.setY(pivot.getTranslateY()); + this.pivot.setZ(pivot.getTranslateZ()); + } + + /** + * Set distance of camera from pivot + * @param distance in units + */ + public void setDistance(double distance) { + this.distance.setZ(-distance); + } + + /** + * Set angle of camera from z-axis along ground + * @param yaw in degrees + */ + public void setYaw(double yaw) { + this.yaw.setAngle(yaw); + } + + /** + * Set elevation of camera + * @param pitch in degrees + */ + public void setPitch(double pitch) { + this.pitch.setAngle(-pitch); + } } From cc66d63096939e5dcdc64f7c8dd582cafe22e40e Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Wed, 30 Aug 2017 15:18:08 +1200 Subject: [PATCH 10/51] Removed unused shapes list from View3D #story[1196] --- .../src/main/java/visualiser/model/View3D.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/model/View3D.java index 9748fc8f..936b7fbc 100644 --- a/racevisionGame/src/main/java/visualiser/model/View3D.java +++ b/racevisionGame/src/main/java/visualiser/model/View3D.java @@ -18,12 +18,18 @@ import java.util.List; * sky box, whose textures are set with special methods. */ public class View3D extends Pane { + /** + * Rendering container for shapes + */ private Group world; - private List shapes; - + /** + * Near limit of view frustum + */ private double nearClip; + /** + * Far limit of view frustum + */ private double farClip; - /** * Position camera pivots around */ @@ -45,7 +51,6 @@ public class View3D extends Pane { * Default constructor for View3D. Sets up Scene and PerspectiveCamera. */ public View3D() { - shapes = new ArrayList<>(); world = new Group(); SubScene scene = new SubScene(world, 300, 300); @@ -86,7 +91,6 @@ public class View3D extends Pane { * @param shape to add */ public void addShape(Shape3D shape) { - shapes.add(shape); world.getChildren().add(shape); } From c2fd5c9baeba84c87663d70e004890c7e9e0c63e Mon Sep 17 00:00:00 2001 From: Connor Taylor-Brown Date: Wed, 30 Aug 2017 15:49:20 +1200 Subject: [PATCH 11/51] Changed box to boat mesh - Mesh needs to be rotated -90 degrees on X - STL file has been added to assets #story[1196] --- .../Controllers/HostController.java | 20 ++++++++++++++---- .../main/java/visualiser/model/View3D.java | 3 --- .../resources/assets/V1.2 Complete Boat.stl | Bin 0 -> 30984 bytes 3 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 6d11e65e..ed34a2c6 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -1,5 +1,6 @@ package visualiser.Controllers; +import com.interactivemesh.jfx.importer.stl.StlMeshImporter; import javafx.fxml.FXML; import javafx.scene.control.Alert; import javafx.scene.control.ButtonType; @@ -8,6 +9,9 @@ import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.shape.Box; +import javafx.scene.shape.Mesh; +import javafx.scene.shape.MeshView; +import javafx.scene.transform.Rotate; import mock.app.Event; import mock.exceptions.EventConstructionException; import visualiser.model.View3D; @@ -59,10 +63,18 @@ public class HostController extends Controller { view3D = new View3D(); playerContainer.add(view3D, 0,0); - Box box = new Box(100, 100, 100); - view3D.addShape(box); - view3D.setPivot(box); - view3D.setDistance(500); + URL asset = HostController.class.getClassLoader().getResource("assets/V1.2 Complete Boat.stl"); + + StlMeshImporter importer = new StlMeshImporter(); + importer.read(asset); + MeshView mesh = new MeshView(importer.getImport()); + + mesh.getTransforms().add(new Rotate(-90, Rotate.X_AXIS)); + + view3D.addShape(mesh); + view3D.setPivot(mesh); + view3D.setDistance(50); + view3D.setYaw(45); view3D.setPitch(20); } diff --git a/racevisionGame/src/main/java/visualiser/model/View3D.java b/racevisionGame/src/main/java/visualiser/model/View3D.java index 936b7fbc..bd4b4dd0 100644 --- a/racevisionGame/src/main/java/visualiser/model/View3D.java +++ b/racevisionGame/src/main/java/visualiser/model/View3D.java @@ -9,9 +9,6 @@ import javafx.scene.shape.Shape3D; import javafx.scene.transform.Rotate; import javafx.scene.transform.Translate; -import java.util.ArrayList; -import java.util.List; - /** * Control for rendering 3D objects visible through a PerspectiveCamera. Implements Adapter Pattern to * interface with camera, and allows clients to add shapes to the scene. All scenes contain sea plane and diff --git a/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl b/racevisionGame/src/main/resources/assets/V1.2 Complete Boat.stl new file mode 100644 index 0000000000000000000000000000000000000000..a952ca7739aa8326a2ba076af6254834bb61886a GIT binary patch literal 30984 zcmb7NcYqZ|@-9Inm=O?H7XdS}ps-8W7v?QVNs6b35=A7cpd=;wh#~@t5)@DY5iyY$ zHof=yp}>g*Ns4eN!l{_ENRZ`MH8VBy&EEa<^N+iBYwGLn>h9|9>iV9oM?UuG(BXai z)b2O*(LuFaJkob?pT0x08Z~IzwDyg|M)ay6-qI#unP`QpAySm6HX=C)FE8GheDvUxW=8c+;nK5lGpu!f>h{Yz zg|CK|V43I@))>MXqK^{QMkJ?>4zQ{*5)G_gyTcabc9&1)|Ki+q(Tecc|KR$YY^z@DO z3`*XwTxg~CT^xJu^}ZG&IsI63wx#vS%4-AjN+dczPG;$BCRhP zV0~JDX0*kzMJenpTA@aTkFC|48^r4EKErj-oioT9d(pt?2|BQ(-annS zKF&E~)lSYa8=6r}%hg}Wj1g62jUPuk8Yofi=euRbv@A$OJxgj?6JDL28oMpmpdZBD z0PRM!wqK_8%3mu|g|{{_C_(!mlC+*^GJCkk*(dH}pLlii2UFj)?w%^^)zsS&Ep2l! zN4=R+-_K~t` zBNEXwBMwEs7+TZxUzBBQ=njChUCNK2t-SHTTA5eJS>rR-xQ#V}5~3sJFW9*0Hu=im zONdrJe4?aPvMBfb(zsRQ#}}j9rz|lY_Bre0o_{SheWsUPE89O^9Ue0FWbr~?QG%tb z2-idqsm;8R*1)C1qw=+S2Js*0MYX*3UhyTOG0fFKiE4|-(Xt>BUG{A^>+v^NrkXzX zekw5AyH}1qwXaFK*+manz5hBtwru{`boloZtg-k+SL+`mO{(FHf)q;7uOJfdwWDiU zmFNAQ+*8~pFcWdc?1B1-uHAlvb=Ty{sb`nu7?dC`&S|lb{NtR}9?VF2d(pSsR{U4l z-#=v66g~Y)B&v;NXa88uUr#=KO>y*Oo6sGLUx@x)cUF4vL%m{;FM2N8eeAF1+1rd= z{x)23-VD)eaz0 z?IR}I|N6#}8r25bzGN=faShi|%D!ZD+a9Uv0|rFVuMj=B^@r%Gftk_!p1I$k1pSAU z6^Up2vL~$t8Oi3K_TH1kSt8}9b6T0KpL<&?H(e6jH0K2~yPNET3;V>a!xKMB9KUc< z5+yi~5s4^&*j3h>Ltl(^O0^AmIBX%-N0jq+1FK`x8$*q54B2y6TY|Va^Lg*1*P=U~ zJQ$gH#}M0ApMO5oD*W-X1fC|(vfc7qhpa}mrn5iTckS}%kX<)KyWTn2phWC*mH zwgXd=QdT5;0O=|AqEE0Fjq#X&!F3dK9oKUCOV;?1HRLNS6HNfWixSmFB&QBtgLvxG z6(y@k%l;Zv4V0+1e5GY)4L;E|r|5E1l>0NUtbN~fjb2taGj{V~Idc--dVXfC;^$8J zf=$h>+Zu?6d-B3@#gEO~lKYjr7FE(HJu|wbYuK9Fq_hmuun%rCf939twtxPY=yzWY zw_e(t_RiGrmYnj+w#hqHi+J` zV@T@S&F99hZ(fvY*Wp2{(ceE>9U64CUVE^QcTRLX^{D5^S-U?T8~JVN=_LAaJR2es zQMr*h)|U2_B6WLa8(eodW3WD=RcGp0SslNRRI1#{pagLdiRjdteYeU#t&%!Wg7qPi%srwOd}G7Ir!LA#-)omOeQq_p3Ph(?4k;t`A*h>qpPOHfkK zt+E#{K_sV+g>DoF+m1H~tdD3*`RVI4?t>ESEg}&OYLK1%21ld%bNmXeC|~IbM^=}5 zTB3H7wlg)^^>BGN z0)!}}+h_ct$%AUcqM0^Q)9P~t8 z`mc!mC*ZHfy6YSz-S{iM~{P^p)+gG@ch*$!|G*=_mNhip%(Che%>KqN#4r5f@ifN3O&7S3S;O znk{DrIc1;(>q8``j#lh_ma_Lj&ydk)Ra9eddOG+0RW55Zetd8WB>~?R@IL6TaE4c* z@llP#VSP@k*0aCb!~O~-*g`}iy3}k~r~V4)1#$ zweskc)b`dR8!WRlGq(7vGuEB4AFNn~_Ewv|rCzz*i&w>h8v2z;RJ$SH;=x?3_h^WsUb-4V0*Mg*F*6Eenz$6RCCa&7y=H`eV{zuy z^l{@$8t&bbJAm&|IIm><{hLrQUN+vUcKpP;fA*}GgXbL?HUA9fpM3?1=aRdhOIi1D z-1YI?MRb}rglAkbA-wun+>29*P3q1o7dzf^Z2Fw488Pe=(UOkul?;9Gc)0PAxP=n6 zkJt)rNOVoP4dK~t9jJkI=!%lnMb!V5HxsYDOp)!o;}%NLZivJdd}e1!M%&jDQ+PZO zcl)Y}vESaDZ6>YEEE5Z_zV4myw7f-$W?#jF zY7Ka>gLTXNt77Q+h?@Sit)zF$($IT<#{=F{hDg1T}Owkez|3VUG#LA1tU8+QW6A1TBh4 zY~7<(iq6}a5!%ffdP0(@3f6(Gl~qSHD_u9Vqf9^aK8SHqCyLX0QpKXX*VG8@Weq)% zi3D4S^*MDEZOgQ+ixO-hA~_nvRy%PYeSLFk_h0_xD~SR1zFTb7zHN5V16@DN{hnKe z5{(-D!CwWD3T|9p^2o${L)$o}kI_@~48c`9;Jenzp34@77cLL_5~)u;Dk2e;9EqE1 zf1I$h4)g^}-nn$u%8smM$CnhdMo(7*C8{lJUdw_+H0hhTwY%fL6VeJ@sS>-_*)FkA zEzA0MH0s^qXrM&3#iMH3c?D=z?UT@g(zw0*t3@Rar(-Us7cDz;w=-yp_>+}^s_Hc|eYfKL7i1*3ooc+~0ovN$bfc;*t9YEKj0D*NUtttdHo9F{`52P0fj% zoBNm@vs7E*Ne}x()M)9U=+2zl(Z44?7>L%2ebl-^Tgm#?S7eOi2VY|R7aIBAzjI1i z-)^L=@qI)h`tazO;zEwMf5ToBBj%!^k#s4aZho7|94_(ppB8T^xt=mYudo+I$rlgI zjaF&Y()|0~(lSVu_*MT8_f=naGPyhH%$JvZEz4=Z$pgqNlQ|#~)s{PzmIcYlvgqt) zS>UMQXlhx`5{}00WimNLqT1p)wd}ku{qpw2V(X5~&)T}n^<4$M zvzEnc2Q`8c+>w1GBGY(lex%{H+#kxE8E{7qBE^^H7M1=~J+zNCP=b3&@XQduazXZd z_m+y00*oL8@3`~wd<~S~T^5nVI-DWoMuerTS$Y`R#Q3Fr!x4Jcc!cAkWhEN%ly4M? z@jRz(Lf2>4Uvd$e`|kZiIGXv0Ou=4API6ph*~{;yB$xo;|w6dd5lPW zdt9`o4=y^^~eTc+aF5@<3>l;1V2P3J$oSCP-Kj7`>0SVX*k%*cN z$n@S=5Emnm!5pTSR(z8$-bZ{1O0YgeB6@7b+VJu1<3hjw?B9f?w`c{-5F`5Gr6$F{ zhYQ04SOX<`cb4~4v>VZxzgy)|Epn($AmanwzN490El0NZabz1Kw3tD6)yS>q$tKndChk(@f7bv*;lB|g1)QSM;A@XbGc zlr0fRS?4IhIfh6ahkN@}zP^$nE=IZ02Rp5j4D6wtPmL0+50QxaoZ6fHE=RWe@hchj z5O)CF8Js#qLo&%xg4RVOqW?U<89|NPNoJ5x17^%8YDzuR^%E z;lOC>@ebLyq(u{vD7E@!FP{_6A?+Rf3prAtO(+m8>IpakuMNJMqqF)!i~#J1yCs766_Nq@f#$cE;`m3Q{3?6>RjpV%D%@;_2+BmiFK!anUOAB9=6Lr9(*$W z`VaMZ?jB%`y606dp7!rbA^A!rqW$-vt!X;1LLMS4+Y8HSS;yl*H!Wl&J8~QggDkeB~o?gr03RntPt&p5r+|zS4WmRjj?Z z;2!hOT+u!kG*D8r`mE^cRh`WG&b?wmBv~I_I@c}Oz+;ZMQr12NTR56EwmzIw@cE9z zB`CrAf=HKebhEhSHQ}mtzYn2(uqD_+q8{u+Hm_(Jj@CFFLJ8Upk%%5T5jR(7whg^; z%kYHE#3swXHGfU5nJ07i%jECo?i^#!C-!!>9A5SWSB5^N#S2KGLGuW23rXQjg-l%W5> zvEh5vgqo3G&u?ljE@)(-MR7&pO5;~V*7%Dxs;~x1#0RfA9Zx^?pL+Iq=-3b)%xV#N z>h!S zTg{Zk`iL%OjrpuGj5Sb#xQIm5cJ-gO54n*?QY1as%}Q$>n#+sz@ohWdXxzjaC_!9A zBI0PXnOXjm=DVhCDi(`&tZ-F&!K>lG3`Z;QO9Nwvj`t5`k6dc|cC|Z>2O<%1EZ@k= zKlH+t_Ds}uhb_St@+&gev7*C^xx4ZUY+s_*MO#T(k$6|@aV#9ZteWYN-^rdO>d&zy z*g~S6cRCuKSOXzHu$nA}@Wt}aFi_7<(c`*~q- z4Qkubt4UecBhjOvffDQ!T7e@cbNeL|^F~=M@9Lhyw&R%N9OL)edHs^bt_Di5Pl&`U zAwI8fI`eADk{Vxx5En-cN0akK`Rw!cfX*f7wTk4T1nWa2q8We0tp&@T4NqM4d0_v* z*%zGc^7bgR|NJLCJa523wOpE{fvJKwPYkv+@QEO3r1Cv8;g- zoJ)wrIl`9@O;F$Ju`vXUs(2IeS#~u z)UvE!zOg3stFlO(QN{7ZM>(FznP6UTIZq;`9A4(G87)f@0MfFkky`0;c(LuGt$85)mYVWezamkdFiNmbK_uqznxig< zmos*ZvVJ))$0&!FbCQi_9@;!%lfgXUKFkwF3Fj>t|T%fBI;R5_~hcmJij ztOiOn_Ffi=JrKuageQzMj^i^)WU^wJTf!Q`MHVcS=xj$MqBq0E1@fh|jw4VhWENwb z$>$HJ4t30t?=`o}mju|LfW$muGtlJ;;~4N8tx=vZzvCL8S-h@jfH~xHkx_zUgGkaI z`NtU(j>DyNJhc43vIu+)DdDJ<)%GKI5`p}Lptj6G(tRmXi%M2VK&R{#%*Xm!6#vygehMa&aM z&xyT7E7)9Qqg-T^;J$=NL|vv^8}x;jW9$iK7K;^-2a7&9=yz3uzBY)&JYl0eVUB;M zl5CDEQb(94+@TD!ShOMEC*?DX z=d#AE)%DB;YCv~rOV$>s?g;R(-Vo-oct{0g;gF0#4Q%rC(* zu1AMsA}@-f?MYzW1(Eu0{UP-=^Mt!HPgpzvb@1-%3b7dh3{s^0_RJH$m3hKA`|vB&wzhKwZRGmDvvoKh|_=PG#;JmVsgjG509=C}U@ zasjZc`9+R~a*^fVRKi&V2`!gJlJA@qg{M9(%evDQ_1|j{C0dqsr`paM{JF-sT;&OK zW<^Sw#hgEpQl7B1!q0lLR%SO>E^<)fXSyJg%@ekiC(Q4%Mw!K0b~5c*+hZ0#{=se5 z@61JR!(3#k!y8)n0mYTUW*cDoEhaJBa&0cG?-V~+n^P) zQhbYbnZ->zjLKJTAG75=iP(p|lFLQ*?dH@Gabq%^k&x5~6!TcTm`pG-Avzk9K?%lT z5Xq?nG9aKOehX3C(NHcjO7PBsed1T-nt!ZQo-kSwtt;zMeKW^*8)WB8287Ej_9TL< zaREeP&9=vLB!f=!;V{a@xp4{2heNv&eb#Vd6XhbK1nq-JHcvQ5dBS1`#g($2yb($M zuK$b|X0bPF*edw~kvL1p&0#?w#W`?EA5C0B%3lb-dIt1Fcp`T+BrB|dHBiEtPAQED zB9fz_JYifD_!Vk%CScEj`4WfQ&;AM}oE4PPI2UqK|kuhtx%FTa^7o&kG^J?G3S{uLVMoafZ>Hfu=! z6-va~UL!1Hk6CO@ay3w*Wyyk9ZHHORJYj32&nz~|Eau!wyDaRZ z;JK8!$ktY$S!|y<-Cwrx&Y!C7GmF)i;46vPL|;s#jQ0f2wBXq;zaW4TyblDC9=>Tz zs;kQr#_>Sw;_ZcVSb8l^9b+!?P0U3`3GPdXWb=egHuHo(Wu7peUh%Yykq{#0BAZdn zMgEAn$SA?sG$PqNVY88W!UvfrjHhD!3bk!6vU#eG!$n33_6d<}p0KInGmE`AuHNWf z?yDV>@tDP)hTeW%HkcQ=QEi7=oIQSgNO{6Cf*Kc-vff^T^J>wg*TNNCE;34(YiE>; zTo!4(0cNrH<|U)1=Q%0s=}ff$H?tVeTDZ?MbMnsjLIas6oXy-H*z17_xo@~!WR$4)k!UUUiG4|n3Aw@(7Dg^g&#H=cz+7aPA??MGu?|FX>R7`(VbRbNS=m?*Y7^bN`Ml;G zn2RhdA(UXB5Q$&m7H2oV-{lGGd!5vwksF8Mw+(C_(R2775Qyessugp%+i`>yy6+HMAun(OZ#}l}SKU z%@Zdx*rhyYZQ3tjk5ls60mNF-FQe z&d%DVlgoET3C2PZiHNz#<|uQKdoULnadEcm_&cxq+e$~9w#;|_i}}td!TJ!1sPWQ6 zsgIb8T*_Qz>>>6XTgVx|V^*bZbotIG!Sg2~iC^)#$Qb#Tzw0Z2l=0ojiA=~WK?%MO z1(CMCx+SDsWQ^l;Mtn-S$bzI<{#@EWCRh2+L5UyvMrW*d9A#tGp=nMH5^U;?N8Q_*pe{AP=ae7k!&t< z$^T+6%V_FOjeb6;ff6k{zeeF`JHId6Y-n!tlP(t-PZPQu$eBvDo%6$#l?$?4xO``n z;5h-2ILjh$LH;uC`7rJ|#xL;pi??DTW-sRp-&s5yN-(a0NMaG6i!5c$FqE=JHp@ml zc}L)At^5uoN`moLM7sNi3Au0jzggqOGH_<#jNzNtRXNR-?~D?)n~aBA+KFXMzGHm; zIPST42J9_b0p}QV`!2gVU*m}=!MTJ;MD>Tv&X?GdSQlp>&Psw;Yq25tE0AC$6_JQ) z-c~NGTx48#y4T7HDVWL8V$qh+LFPNluPvYi*CQekZRh*oQ|^5baq&bJ%r&_v_FL#m z<~v`-b)W?6LnNX%x_#;G=h$1cPaw<2*3j`l2}XniNYp#0VvcwQ84vslwK40-84rEO zK?z1u5sCk61yh^kDi;~;qxW;+A_w!Lr|)>Ss$s>y__}63iDwB+d}p)gxa|`-rP$x$h{Flx@DVr-2eJOG{MSX%%yk?d(sf z2kj$v_iqr$UhWXeS?7+5CI7EkrD(Sx($p*Ku9tZGZjPQ~+!%X{R&daj?~D@6bwwni z4$G>pS1vNn44g5T#q89fd}oyKdB=;&Ba)*5Z+G5Ts2%jEC#-L>RRbj$d&l~mI##;z zcI+Yc9QP8AOq|-AFB%eWM+xp3h{W8C`W3=^PiBR$VWu1NYg5WzW`09Txhu^7h$st& z^T6NS5o+r4ol(N9--z;^5s7nH9_cg$Du z2x3dHg;*a^#$(PbNw5Y=5EqebF0xTBvRF~s%TiWenT(Bclx@DV*~EP3Eap3-M9Ru) zLnNEMoD}wQ7v_@5iUg)_7?@8fpS{d{XHP@2|5So|Eg}(B=AH|CxrBR;yFRl_Q_4kV zUTWB9FL!h`gzp@b_%|U$az^k!59JgbVJ@=NuJW)7CuCr6_j^PP)$%!3l&3W#KL zkxdD6k;BYI#@?b8uuseYJsmem<~v`^d}owk+YyP+K7Yoo>zIoiVJ@=FL}ju`S$UT- zE0v>c^PR1_%y)i^`OYYjva%%+$>t*4-lu@Ai><=hhqIFJgFGI>cP?ZNl%RDH$>t(k zFJ0fV;1cE{<5#GStIP3MU-rr=813)}y>*9UgGl^)04L+-;sGv870_uMB?9}pHMR?T;$3Qd)XTU@uuGmUiQ3!^jtG=aW1gG>fST?GINpdci78e;MaQf zp*GLN9zB!uSYxWgUiNUsKAQ0>W1~o%N0#{0UVFkt7KyT#@hjBk-+o-}Xb9gKB~sQ5 zV??sK$ks5Ii!5WHyi^~DR=hsNqG8efSbCIzn*g~9@Hs9I0f%(p>nD2}dv>PIE zl(W!ZQPN&*3AP Date: Wed, 30 Aug 2017 17:16:15 +1200 Subject: [PATCH 12/51] Created scene to view/update current key bindings. - Current key bindings are shown on buttons - Added button action events to store the clicked button - Added key press event to entire pane - Button text is updated to display its key - Added functionality to keyFactory to update key bindings - CSS styling for some components #story[1197] --- .../Controllers/KeyBindingsController.java | 116 ++++++++++++++++++ .../src/main/java/visualiser/app/App.java | 12 +- .../gameController/Keys/KeyFactory.java | 8 ++ .../src/main/resources/css/keyBindings.css | 35 ++++++ .../visualiser/scenes/keyBindings.fxml | 25 ++++ 5 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java create mode 100644 racevisionGame/src/main/resources/css/keyBindings.css create mode 100644 racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml diff --git a/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java new file mode 100644 index 00000000..77b6687f --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/Controllers/KeyBindingsController.java @@ -0,0 +1,116 @@ +package visualiser.Controllers; + +import javafx.application.Platform; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.input.KeyEvent; +import visualiser.gameController.Keys.ControlKey; +import visualiser.gameController.Keys.KeyFactory; +import java.util.Map; + +public class KeyBindingsController { + @FXML Button btnSave; + @FXML Button btnCancel; + @FXML Button btnReset; + @FXML ListView lstControl; + @FXML ListView lstKey; + @FXML ListView lstDescription; + @FXML Label lblTitle; + String currentButton = null; + KeyFactory keyFactory = KeyFactory.getFactory(); + + public void initialize(){ + + lstKey.getItems().add("Key"); + lstControl.getItems().add("Command"); + lstDescription.getItems().add("Description"); + + + + for (Map.Entry entry : keyFactory.getKeyState().entrySet()) { + Button button = new Button(entry.getKey()); + button.setMinWidth(120); + button.setOnAction(new EventHandler() { + @Override public void handle(ActionEvent e) { + currentButton = button.getText(); + System.out.println("Button clicked"); + } + }); + lstKey.getItems().add(button); + lstControl.getItems().add(entry.getValue()); + lstDescription.getItems().add(entry.getValue().getProtocolCode()); + } + + lstKey.getSelectionModel().select(0); + lstControl.getSelectionModel().select(0); + lstDescription.getSelectionModel().select(0); + + lstKey.getSelectionModel().selectedItemProperty() + .addListener((observable, oldvalue, newValue) -> { + Platform.runLater(new Runnable() { + public void run() { + lstKey.getSelectionModel().select(0); + } + }); + }); + lstDescription.getSelectionModel().selectedItemProperty() + .addListener((observable, oldvalue, newValue) -> { + Platform.runLater(new Runnable() { + public void run() { + lstDescription.getSelectionModel().select(0); + } + }); + }); + lstControl.getSelectionModel().selectedItemProperty() + .addListener((observable, oldvalue, newValue) -> { + Platform.runLater(new Runnable() { + public void run() { + lstControl.getSelectionModel().select(0); + } + }); + }); + + lstKey.sceneProperty().addListener((obs, oldScene, newScene) -> { + if (newScene != null) { + newScene.getStylesheets().add("/css/keyBindings.css"); + } + + }); + } + + public void cancel(){ + System.out.println("cancel clicked"); + } + + public void reset(){ + System.out.println("reset clicked"); + } + + public void save(){ + System.out.println("save clicked"); + } + + public void onKey(KeyEvent e){ + System.out.println("key pressed"); + // if a button was clicked + if (currentButton!=null){ + // update text on the button + ObservableList buttons = lstKey.getItems(); + for (int i = 1; i < buttons.size(); i++) { + if (currentButton == ((Button)buttons.get(i)).getText()) { + ((Button)buttons.get(i)).setText(e.getCode().toString()); + break; + } + } + // update the control key + keyFactory.updateKey(currentButton, e.getCode().toString()); + // remove current button selection + currentButton = null; + } + } +} diff --git a/racevisionGame/src/main/java/visualiser/app/App.java b/racevisionGame/src/main/java/visualiser/app/App.java index eeae5a5d..92cb3096 100644 --- a/racevisionGame/src/main/java/visualiser/app/App.java +++ b/racevisionGame/src/main/java/visualiser/app/App.java @@ -3,7 +3,6 @@ package visualiser.app; import javafx.animation.FadeTransition; import javafx.application.Application; import javafx.application.Platform; -import javafx.beans.property.ReadOnlyObjectProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.concurrent.Task; @@ -15,7 +14,6 @@ import javafx.geometry.Rectangle2D; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.Label; -import javafx.scene.control.ListView; import javafx.scene.control.ProgressBar; import javafx.scene.effect.DropShadow; import javafx.scene.image.Image; @@ -30,8 +28,6 @@ import javafx.stage.WindowEvent; import javafx.util.Duration; import visualiser.Controllers.MainController; -import java.io.IOException; - public class App extends Application { @@ -170,6 +166,14 @@ public class App extends Application { System.exit(0); } }); + + // TODO: remove later, just for testing + Parent root2 = FXMLLoader.load(getClass().getResource + ("/visualiser/scenes/keyBindings.fxml")); + Stage stage2 = new Stage(); + stage2.setScene(new Scene(root2)); + stage2.centerOnScreen(); + stage2.show(); } /** diff --git a/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java b/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java index be95abd3..26267d84 100644 --- a/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java +++ b/racevisionGame/src/main/java/visualiser/gameController/Keys/KeyFactory.java @@ -48,4 +48,12 @@ public class KeyFactory { return keyState.get(key); } + public Map getKeyState() { + return keyState; + } + + public void updateKey(String oldKey, String newKey){ + ControlKey controlKey = keyState.get(oldKey); + keyState.put(newKey, controlKey); + } } diff --git a/racevisionGame/src/main/resources/css/keyBindings.css b/racevisionGame/src/main/resources/css/keyBindings.css new file mode 100644 index 00000000..a1dc8242 --- /dev/null +++ b/racevisionGame/src/main/resources/css/keyBindings.css @@ -0,0 +1,35 @@ +.list-view .list-cell { + -fx-cell-size: 40; + -fx-font-family: "Tahoma"; + -fx-background-color: #fffff0; + -fx-alignment: center; +} + +.list-view .list-cell:even { + -fx-background-color: #ffffdc; +} + +.list-view .list-cell:selected { + -fx-background-color: #f9e5c3; + -fx-font-family: "Comic Sans MS"; + -fx-font-weight: bold; + -fx-font-size: 18; +} + +.button { + -fx-background-color: linear-gradient(#acdeff 50%, #a9c8ff 100%); + -fx-background-radius: 4px; + -fx-border-radius: 4px; + -fx-text-fill: #242d35; + -fx-font-size: 12px; + -fx-font-family: "Courier New"; +} + +.button:focused { + -fx-background-color: white; + -fx-border-color: #0056bd; +} + +#anchor { + -fx-background-color: #fdfac3; +} \ No newline at end of file diff --git a/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml b/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml new file mode 100644 index 00000000..9f881b21 --- /dev/null +++ b/racevisionGame/src/main/resources/visualiser/scenes/keyBindings.fxml @@ -0,0 +1,25 @@ + + + + + + + + + + + +