From 9ac9c2592332b035c86dbb8670cb6bae56cb4313 Mon Sep 17 00:00:00 2001 From: Fan-Wu Yang Date: Mon, 11 Sep 2017 00:54:11 +1200 Subject: [PATCH] Made sea surface look like a sea surface which is randomly generated each time, size may need to be altered a bit else it will cause the program to slow #story[1261] --- .../Controllers/HostController.java | 2 + .../Controllers/RaceController.java | 10 +- .../main/java/visualiser/layout/Plane3D.java | 156 ++++++++++++++++++ .../java/visualiser/layout/SeaSurface.java | 33 ++-- .../main/java/visualiser/layout/View3D.java | 11 +- .../utils/PerlinNoiseGenerator.java | 4 +- 6 files changed, 194 insertions(+), 22 deletions(-) create mode 100644 racevisionGame/src/main/java/visualiser/layout/Plane3D.java diff --git a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java index 10bc9dbe..46acb405 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/HostController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/HostController.java @@ -14,6 +14,8 @@ import javafx.scene.layout.GridPane; import javafx.scene.shape.MeshView; import mock.app.Event; import mock.exceptions.EventConstructionException; +import visualiser.layout.Plane3D; +import visualiser.layout.SeaSurface; import visualiser.layout.Subject3D; import visualiser.layout.View3D; diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java index 3826bba3..d087ebaa 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceController.java @@ -191,21 +191,25 @@ public class RaceController extends Controller { StlMeshImporter importerBurgerBoat = new StlMeshImporter(); importerBurgerBoat.read(alternateBoatAsset); - SeaSurface sea = new SeaSurface(900); - view3D = new View3D(); + view3D = new View3D(false); view3D.setDistance(1050); view3D.setYaw(0); view3D.setPitch(60); view3D.enableTracking(); - canvasBase.add(sea.getSurface(), 0, 0); canvasBase.add(view3D, 0, 0); + // Set up projection from GPS to view RaceDataSource raceData = visualiserRace.getVisualiserRaceState().getRaceDataSource(); final GPSConverter gpsConverter = new GPSConverter(raceData, 450, 450); view3D.setItems(viewSubjects); + //viewSubjects.add(new Subject3D(new MeshView(new Plane3D(50, 50, 1, 1)))); + + SeaSurface sea = new SeaSurface(4000, 200, 250, 210); + viewSubjects.add(sea.getSurface()); + Boundary3D boundary3D = new Boundary3D(visualiserRace.getVisualiserRaceState().getRaceDataSource().getBoundary(), gpsConverter); for (Subject3D subject3D: boundary3D.getBoundaryNodes()){ viewSubjects.add(subject3D); diff --git a/racevisionGame/src/main/java/visualiser/layout/Plane3D.java b/racevisionGame/src/main/java/visualiser/layout/Plane3D.java new file mode 100644 index 00000000..2589662c --- /dev/null +++ b/racevisionGame/src/main/java/visualiser/layout/Plane3D.java @@ -0,0 +1,156 @@ +package visualiser.layout; + +import com.sun.javafx.geom.PickRay; +import com.sun.javafx.scene.input.PickResultChooser; +import com.sun.javafx.sg.prism.NGNode; +import javafx.scene.Node; +import javafx.scene.shape.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by fwy13 on 10/09/17. + */ +public class Plane3D extends TriangleMesh{ + + /** + * Lenght is up down, and width is left right + * @param width + * @param length + * @param subdivisionsWidth + * @param subdivisionsLength + */ + public Plane3D(float width, float length, int subdivisionsWidth, int subdivisionsLength){ + + float subWidth = width / (float) subdivisionsWidth; + float subLength = length / (float) subdivisionsLength; + + ArrayList pointsList = new ArrayList<>(); + ArrayList textureCoord = new ArrayList<>(); + float startW = -width/2; + float startL = -length/2; + + for (float l = 0; l <= length; l += subLength) { + for (float w = 0; w <= width; w += subWidth){ + //add points + pointsList.add(w + startW); + pointsList.add(l + startL); + pointsList.add(0f); + //addTexture coords + textureCoord.add(1 - w/width); + textureCoord.add(1 - l/length); + } + } + + this.getPoints().setAll(copyListToArray(pointsList)); + this.getTexCoords().setAll(copyListToArray(textureCoord)); + + + ArrayList faces = new ArrayList<>(); +// p0 1 2 t2 0 3 +// p2 1 3 t3 0 1 +// faces.add(2); +// faces.add(3); +// faces.add(0); +// faces.add(2); +// faces.add(1); +// faces.add(0); +// faces.add(2); +// faces.add(3); +// faces.add(1); +// faces.add(0); +// faces.add(3); +// faces.add(1); + +// faces.add(1); +// faces.add(1); +// faces.add(0); +// faces.add(0); +// faces.add(3); +// faces.add(3); +// faces.add(4); +// faces.add(4); +// faces.add(1); +// faces.add(1); +// faces.add(3); +// faces.add(3); +// faces.add(2); +// faces.add(2); +// faces.add(1); +// faces.add(1); +// faces.add(4); +// faces.add(4); +// faces.add(5); +// faces.add(5); +// faces.add(2); +// faces.add(2); +// faces.add(4); +// faces.add(4); + int listSize = pointsList.size()/3; + int divsInRow = subdivisionsWidth + 1; + for (int i = 0; i < listSize; i++){ + int row = i/divsInRow; + + if (row < 1){ + continue; + } + + boolean notFirstCol = (i) % divsInRow != 0; + boolean notLastCol = (i + 1) % divsInRow != 0; + if (notFirstCol){ + faces.add(i); + faces.add(i); +// printPointAtIndex(i); + faces.add(i - divsInRow); + faces.add(i - divsInRow); +// printPointAtIndex(i - divsInRow); + faces.add(i - 1); + faces.add(i - 1); +// printPointAtIndex(i-1); + } + if (notLastCol) { + faces.add(i - divsInRow + 1); + faces.add(i - divsInRow + 1); +// printPointAtIndex(i - divsInRow + 1); + faces.add(i - divsInRow); + faces.add(i - divsInRow); +// printPointAtIndex(i - divsInRow); + faces.add(i); + faces.add(i); +// printPointAtIndex(i); + } + + } + this.getFaces().setAll(copyListToIntArray(faces)); + + + } + + private void printPointAtIndex(int index){ + int i = index * 3; + float x = this.getPoints().get(i); + float y = this.getPoints().get(i + 1); + float z = this.getPoints().get(i + 2); + System.out.println(String.format("Point at %d is x:%f, y:%f, z:%f", index, x, y, z)); + } + + private static float[] copyListToArray(List list){ + float[] res = new float[list.size()]; + for (int i = 0; i < list.size(); i++){ + res[i] = list.get(i); + } + return res; + } + + private static int[] copyListToIntArray(List list){ + int[] res = new int[list.size()]; + for (int i = 0; i < list.size(); i++){ + res[i] = list.get(i); + } + return res; + } + + +} diff --git a/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java b/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java index a9395996..6da2e5e3 100644 --- a/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java +++ b/racevisionGame/src/main/java/visualiser/layout/SeaSurface.java @@ -7,6 +7,7 @@ import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import javafx.scene.paint.PhongMaterial; +import javafx.scene.shape.Box; import javafx.scene.shape.MeshView; import javafx.scene.shape.TriangleMesh; import visualiser.utils.PerlinNoiseGenerator; @@ -16,11 +17,13 @@ import visualiser.utils.PerlinNoiseGenerator; */ public class SeaSurface { private float[][] noiseArray; - private ImageView surface; + private Subject3D surface; - public SeaSurface(int size){ - noiseArray = PerlinNoiseGenerator.createNoise(size); + public SeaSurface(int size, double freq, double x, double z){ + noiseArray = PerlinNoiseGenerator.createNoise(size, freq); createSurface(); + surface.setZ(z); + surface.setX(x); } private void createSurface(){ @@ -30,13 +33,14 @@ public class SeaSurface { material.setDiffuseMap(diffuseMap); material.setSpecularColor(Color.WHITE); - // testing / debugging stuff: show diffuse map on chart - ImageView iv = new ImageView(diffuseMap); - //iv.setTranslateX(-0.5 * noiseArray.length); - //iv.setTranslateY(-0.10 * noiseArray.length); - iv.setRotate(90); - //iv.setRotationAxis(new Point3D(1, 0, 0)); - surface = iv; + Plane3D seaPlane = new Plane3D(noiseArray.length, noiseArray.length, 10, 10); + MeshView seaSurface = new MeshView(seaPlane); +// Box seaSurface = new Box(noiseArray.length, 0.1, noiseArray.length); + seaSurface.setMaterial(material); + //seaSurface.setRotationAxis(new Point3D(1, 0, 0)); + //seaSurface.setRotate(90); + + surface = new Subject3D(seaSurface); } /** @@ -61,10 +65,11 @@ public class SeaSurface { gray = clamp(gray, 0, 1); - Color lightBlue = new Color(0.2, 0.2, 1, 1); - Color lighterBlue = new Color(0.25, 0.225, 1, 1); + Color brightBlue = new Color(0.06, 0.5, .78, 1); + Color lightBlue = new Color(0.15, 0.68, .88, 1); + Color lighterBlue = new Color(0.28, 0.73, .91, 1); - Color color = lighterBlue.interpolate(lightBlue, gray); + Color color = Color.WHITE.interpolate(brightBlue, gray).interpolate(lighterBlue, gray).interpolate(lightBlue, gray); pw.setColor(x, y, color); @@ -92,7 +97,7 @@ public class SeaSurface { return value; } - public ImageView getSurface(){ + public Subject3D getSurface(){ return surface; } diff --git a/racevisionGame/src/main/java/visualiser/layout/View3D.java b/racevisionGame/src/main/java/visualiser/layout/View3D.java index 7b7d9a77..2096e3e0 100644 --- a/racevisionGame/src/main/java/visualiser/layout/View3D.java +++ b/racevisionGame/src/main/java/visualiser/layout/View3D.java @@ -90,7 +90,7 @@ public class View3D extends Pane { /** * Default constructor for View3D. Sets up Scene and PerspectiveCamera. */ - public View3D() { + public View3D(boolean fill) { this.world = new Group(); this.selectionMap = new HashMap<>(); this.target = null; @@ -98,13 +98,18 @@ public class View3D extends Pane { scene.widthProperty().bind(this.widthProperty()); scene.heightProperty().bind(this.heightProperty()); - //scene.setFill(new Color(0.2, 0.6, 1, 1)); - + if (fill) { + scene.setFill(new Color(0.2, 0.6, 1, 1)); + } scene.setCamera(buildCamera()); this.getChildren().add(scene); } + public View3D(){ + this(true); + } + /** * Sets up camera view frustum and binds transformations * @return perspective camera diff --git a/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java b/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java index a5093b50..337dc656 100644 --- a/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java +++ b/racevisionGame/src/main/java/visualiser/utils/PerlinNoiseGenerator.java @@ -11,13 +11,13 @@ public class PerlinNoiseGenerator { * @param size * @return */ - public static float[][] createNoise( int size) { + public static float[][] createNoise( int size, double freq) { float[][] noiseArray = new float[(int) size][(int) size]; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { - double frequency = 20.0 / (double) size; + double frequency = freq / (double) size; double noise = ImprovedNoise.noise(x * frequency, y * frequency, 0);