Merge remote-tracking branch 'origin/story1266_3d_model_factory' into NewUI_merge

# Conflicts:
#	pom.xml
#	src/main/java/seng302/App.java
#	src/main/java/seng302/gameServer/GameState.java
#	src/main/java/seng302/gameServer/MainServerThread.java
#	src/main/java/seng302/gameServer/ServerToClientThread.java
#	src/main/java/seng302/utilities/XMLGenerator.java
#	src/main/java/seng302/visualiser/GameClient.java
#	src/main/java/seng302/visualiser/controllers/RaceViewController.java
#	src/main/resources/views/RaceView.fxml
#	src/main/resources/views/StartScreenView.fxml
This commit is contained in:
Michael Rausch
2017-09-11 15:29:33 +12:00
130 changed files with 24554 additions and 331 deletions
@@ -1,4 +1,4 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import java.util.HashMap;
import java.util.Map;
@@ -1,16 +1,25 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import javafx.application.Platform;
import javafx.geometry.Point2D;
import javafx.geometry.Point3D;
import javafx.scene.AmbientLight;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PointLight;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Polyline;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.shape.Shape3D;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Translate;
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
import seng302.visualiser.fxObjects.assets_3D.BoatModel;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
import seng302.visualiser.fxObjects.assets_3D.ModelType;
import java.util.ArrayList;
import java.util.List;
@@ -25,6 +34,17 @@ import java.util.List;
*/
public class BoatObject extends Group {
private static final double MODEL_SCALE_FACTOR = 400;
private static final double MODEL_X_OFFSET = 0; // standard
private static final double MODEL_Y_OFFSET = 0; // standard
private static final int VIEWPORT_SIZE = 800;
private static final Color lightColor = Color.rgb(244, 255, 250);
private static final Color jewelColor = Color.rgb(0, 190, 222);
@FunctionalInterface
public interface SelectedBoatListener {
@@ -32,8 +52,8 @@ public class BoatObject extends Group {
}
//Constants for drawing
private static final double BOAT_HEIGHT = 15d;
private static final double BOAT_WIDTH = 10d;
private static final float BOAT_HEIGHT = 15f;
private static final float BOAT_WIDTH = 10f;
private double xVelocity;
private double yVelocity;
@@ -41,16 +61,18 @@ public class BoatObject extends Group {
private double sailState;
//Graphical objects
private Polyline trail = new Polyline();
private Polygon boatPoly;
// private Polygon boatPoly;
private BoatModel boatPoly;
private Polygon sail;
private Wake wake;
private Group wake;
private Line leftLayLine;
private Line rightLayline;
private double distanceTravelled, lastRotation;
private Point2D lastPoint;
private Paint colour = Color.BLACK;
private Color colour = Color.BLACK;
private Boolean isSelected = false, destinationSet; //All boats are initialised as selected
private boolean isPlayer = false;
private Rotate rotation = new Rotate(0,0,1);
private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>();
@@ -81,20 +103,30 @@ public class BoatObject extends Group {
* polygon.
*/
private void initChildren(double... points) {
boatPoly = new Polygon(points);
boatPoly.setFill(colour);
boatPoly.setFill(this.colour);
boatPoly.setOnMouseEntered(event -> {
boatPoly.setFill(Color.FLORALWHITE);
boatPoly.setStroke(Color.RED);
boatPoly = makeBoatPolygon();
boatPoly.getAssets().getTransforms().addAll(
// new Rotate(-40, new Point3D(1,0,0)),
rotation
// new Rotate(-90, new Point3D(0,0,1))
);
boatPoly.getAssets().getTransforms().add(new Scale(5, 5, 5));
// boatPoly.setDrawMode(DrawMode.FILL);
// boatPoly.setFill(colour);
// boatPoly.setFill(this.colour);
// boatPoly.setMaterial(new PhongMaterial(this.colour));
boatPoly.getAssets().setOnMouseEntered(event -> {
// boatPoly.setFill(Color.FLORALWHITE);
// boatPoly.setStroke(Color.RED);
// boatPoly.setMaterial(new PhongMaterial(Color.FLORALWHITE));
});
boatPoly.setOnMouseExited(event -> {
boatPoly.setFill(colour);
boatPoly.setFill(this.colour);
boatPoly.setStroke(Color.BLACK);
boatPoly.getAssets().setOnMouseExited(event -> {
// boatPoly.setMaterial(new PhongMaterial(this.colour));
// boatPoly.setFill(colour);
// boatPoly.setFill(this.colour);
// boatPoly.setStroke(Color.BLACK);
});
boatPoly.setOnMouseClicked(event -> setIsSelected(!isSelected));
boatPoly.setCache(true);
boatPoly.getAssets().setOnMouseClicked(event -> setIsSelected(!isSelected));
boatPoly.getAssets().setCache(true);
// boatPoly.setCacheHint(CacheHint.SPEED);
// annotationBox = new AnnotationBox();
@@ -104,8 +136,8 @@ public class BoatObject extends Group {
rightLayline = new Line();
trail.getStrokeDashArray().setAll(5d, 10d);
trail.setCache(true);
wake = new Wake(0, -BOAT_HEIGHT);
wake.setVisible(true);
wake = ModelFactory.importModel(ModelType.WAKE).getAssets();
sail = new Polygon(0.0,BOAT_HEIGHT / 4,
0.0, BOAT_HEIGHT);
@@ -115,15 +147,65 @@ public class BoatObject extends Group {
sail.setFill(Color.TRANSPARENT);
sail.setCache(true);
super.getChildren().clear();
super.getChildren().addAll(boatPoly, sail);
PointLight pointLight = new PointLight(Color.WHITE);
// pointLight.setLightOn(true);
pointLight.getTransforms().add(new Translate(0, 0, -30));
super.getChildren().add(pointLight);
// pointLight = new PointLight(Color.WHITE);
//// pointLight.setLightOn(true);
// pointLight.getTransforms().add(new Translate(50, 50, -20));
// super.getChildren().add(pointLight);
// pointLight = new PointLight(Color.WHITE);
//// pointLight.setLightOn(true);
// pointLight.getTransforms().add(new Translate(50, -50, -20));
// super.getChildren().add(pointLight);
// pointLight = new PointLight(Color.WHITE);
//// pointLight.setLightOn(true);
// pointLight.getTransforms().add(new Translate(-50, -50, -20));
// super.getChildren().add(pointLight);
AmbientLight light = new AmbientLight(new Color(0.5,0.5,0.5,1));
super.getChildren().add(light);
super.getChildren().addAll(boatPoly.getAssets());
}
public void setFill (Paint value) {
public void setFill (Color value) {
this.colour = value;
boatPoly.setFill(colour);
PhongMaterial pm = new PhongMaterial(this.colour);
for (int i=0;i<2;i++) {
Shape3D s = (Shape3D) boatPoly.getAssets().getChildren().get(i);
s.setMaterial(pm);
}
trail.setStroke(colour);
}
public BoatModel makeBoatPolygon () {
// StlMeshImporter importer = new StlMeshImporter();
// importer.read(getClass().getResource("/meshes/hollow_simple_boat.stl").toString());
// importer.read(getClass().getResource("/cube.stl").toString());
// importer.read(getClass().getResource("/meshes/simple_yacht.stl").toString());
// ObjModelImporter importer = new ObjModelImporter();
// ColModelImporter importer = new ColModelImporter();
// ColModelImporter importer = new ColModelImporter();
// importer.read(getClass().getResource("/meshes/hollow_simple_boat.dae"));
// MeshView mesh = importer.getImport()[0];
// FileInputStream inputStream = null;
// try{
// inputStream = new FileInputStream(getClass().getResource("/meshes/simple_yacht.stl").toString());
// Obj obj = ObjUtils.convertToRenderable(
// ObjReader.read(inputStream));
//
// IntBuffer indices = ObjData.getFaceVertexIndices(obj);
// FloatBuffer vertices = ObjData.getVertices(obj);
// FloatBuffer texCoords = ObjData.getTexCoords(obj);
// MeshView
// FloatBuffer normals = ObjData.getNormals(obj);
return ModelFactory.boatGameView(BoatMeshType.DINGHY, colour);
// } catch (Exception e) {
// e.printStackTrace();
// return null;
// }
}
/**
* Moves the boat and its children annotations to coordinates specified
* @param x The X coordinate to move the boat to
@@ -134,27 +216,27 @@ public class BoatObject extends Group {
* @param windDir .
*/
public void moveTo(double x, double y, double rotation, double velocity, Boolean sailIn, double windDir) {
Double dx = Math.abs(boatPoly.getLayoutX() - x);
Double dy = Math.abs(boatPoly.getLayoutY() - y);
Double dx = Math.abs(boatPoly.getAssets().getLayoutX() - x);
Double dy = Math.abs(boatPoly.getAssets().getLayoutY() - y);
Platform.runLater(() -> {
rotateTo(rotation, sailIn, windDir);
boatPoly.setLayoutX(x);
boatPoly.setLayoutY(y);
if (sailIn) {
// sail.getPoints().clear();
// sail.getPoints().addAll(0.0, 0.0, 4.0, 1.5, 8.0, 3.0, 12.0, 3.5, 16.0, 3.0, 20.0, 1.5, 24.0, 0.0);
// sail.getPoints().addAll(0.0, 0.0, 24.0, 0.0);
sail.setLayoutX(x);
sail.setLayoutY(y);
} else {
animateSail();
sail.setLayoutX(x);
sail.setLayoutY(y);
}
boatPoly.getAssets().setLayoutX(x);
boatPoly.getAssets().setLayoutY(y);
// if (sailIn) {
//// sail.getPoints().clear();
//// sail.getPoints().addAll(0.0, 0.0, 4.0, 1.5, 8.0, 3.0, 12.0, 3.5, 16.0, 3.0, 20.0, 1.5, 24.0, 0.0);
//// sail.getPoints().addAll(0.0, 0.0, 24.0, 0.0);
// sail.setLayoutX(x);
// sail.setLayoutY(y);
// } else {
//// animateSail();
// sail.setLayoutX(x);
// sail.setLayoutY(y);
// }
wake.setLayoutX(x);
wake.setLayoutY(y);
});
wake.setRotation(rotation, velocity);
// wake.setRotation(rotation, velocity);
// rotateTo(rotation);
// boatPoly.setLayoutX(x);
// boatPoly.setLayoutY(y);
@@ -183,35 +265,33 @@ public class BoatObject extends Group {
private void rotateTo(double heading, boolean sailsIn, double windDir) {
boatPoly.getTransforms().setAll(new Rotate(heading));
if (sailsIn) {
rotation.setAngle(heading);
wake.getTransforms().setAll(new Rotate(heading, new Point3D(0,0,1)));
if (!sailsIn) {
boatPoly.showSail();
Double sailWindOffset = 30.0;
Double upwindAngleLimit = 15.0;
Double downwindAngleLimit = 10.0; //Upwind from normalised horizontal
Double normalizedHeading = normalizeHeading(heading, windDir);
if (normalizedHeading < 180) {
sail.getTransforms().setAll(new Rotate(windDir + 90 + sailWindOffset));
sail.getPoints().clear();
sail.getPoints().addAll(0.0, 0.0, 4.0, -1.5, 8.0, -3.0, 12.0, -3.5, 16.0, -3.0, 20.0, -1.5, 24.0, 0.0);
if (normalizedHeading > 90 + sailWindOffset){
sail.getTransforms().setAll(new Rotate(heading + downwindAngleLimit));
}
if (normalizedHeading < sailWindOffset + upwindAngleLimit){
sail.getTransforms().setAll(new Rotate(heading + 90 - upwindAngleLimit));
boatPoly.rotateSail(90 - upwindAngleLimit);
} else if (normalizedHeading > 90 + sailWindOffset){
boatPoly.rotateSail(downwindAngleLimit);
} else {
boatPoly.rotateSail(90 + sailWindOffset);
}
} else {
sail.getTransforms().setAll(new Rotate(windDir + 90 - sailWindOffset));
sail.getPoints().clear();
sail.getPoints().addAll(0.0, 0.0, 4.0, 1.5, 8.0, 3.0, 12.0, 3.5, 16.0, 3.0, 20.0, 1.5, 24.0, 0.0);
if (normalizedHeading < 270 - sailWindOffset){
sail.getTransforms().setAll(new Rotate(heading + 180 - downwindAngleLimit));
}
if (normalizedHeading > 360 - (sailWindOffset + upwindAngleLimit)){
sail.getTransforms().setAll(new Rotate(heading + 90 + upwindAngleLimit));
boatPoly.rotateSail(90 + upwindAngleLimit);
} else if (normalizedHeading < 270 - sailWindOffset){
boatPoly.rotateSail(180 - downwindAngleLimit);
} else {
boatPoly.rotateSail(90 - sailWindOffset);
}
}
} else {
sail.getTransforms().setAll(new Rotate(windDir));
boatPoly.hideSail();
}
}
@@ -222,8 +302,8 @@ public class BoatObject extends Group {
double period = 10;
for (int i = 0; i < 50; i++) {
points[i * 2] = amplitude * Math.sin(((Math.PI * i) / period + sailState));
points[i * 2 + 1] = (BOAT_HEIGHT * i) / BOAT_HEIGHT / 2;
points[199 - (i * 2)] = (BOAT_HEIGHT * i) / BOAT_HEIGHT / 2;
points[i * 2 + 1] = (double) (BOAT_HEIGHT * i) / BOAT_HEIGHT / 2;
points[199 - (i * 2)] = (double) (BOAT_HEIGHT * i) / BOAT_HEIGHT / 2;
points[199 - (i * 2 + 1)] = amplitude * Math.sin(((Math.PI * i) / period + sailState));
}
if (sailState == - 2 * Math.PI) {
@@ -237,6 +317,7 @@ public class BoatObject extends Group {
}
public void updateLocation() {
// boatPoly.getTransforms().add(new Rotate(2, new Point3D(1,1,1)));
// double dx = xVelocity / 60;
// double dy = yVelocity / 60;
//
@@ -346,33 +427,33 @@ public class BoatObject extends Group {
}
public Double getBoatLayoutX() {
return boatPoly.getLayoutX();
return boatPoly.getAssets().getLayoutX();
}
public Double getBoatLayoutY() {
return boatPoly.getLayoutY();
return boatPoly.getAssets().getLayoutY();
}
/**
* Sets this boat to appear highlighted
*/
public void setAsPlayer() {
boatPoly.getPoints().setAll(
-BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
0.0, -BOAT_HEIGHT / 1.75,
BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
);
boatPoly.setStroke(Color.BLACK);
boatPoly.setStrokeWidth(2);
boatPoly.setStrokeLineCap(StrokeLineCap.ROUND);
// boatPoly.getPoints().setAll(
// -BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75,
// 0.0, -BOAT_HEIGHT / 1.75,
// BOAT_WIDTH / 1.75, BOAT_HEIGHT / 1.75
// );
// boatPoly.setStroke(Color.BLACK);
// boatPoly.setStrokeWidth(2);
// boatPoly.setStrokeLineCap(StrokeLineCap.ROUND);
isPlayer = true;
animateSail();
}
public void setTrajectory(double heading, double velocity, double windDir) {
wake.setRotation(lastHeading - heading, velocity);
rotateTo(heading, false, windDir);
// wake.r(lastHeading - heading, velocity);
// rotateTo(heading, false, windDir);
xVelocity = Math.cos(Math.toRadians(heading)) * velocity;
yVelocity = Math.sin(Math.toRadians(heading)) * velocity;
lastHeading = heading;
@@ -1,4 +1,4 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
@@ -1,4 +1,4 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Line;
@@ -1,4 +1,4 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import javafx.scene.Group;
import javafx.scene.paint.Color;
@@ -1,4 +1,4 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import java.util.ArrayList;
import java.util.List;
@@ -7,13 +7,16 @@ import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Scale;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
import seng302.visualiser.fxObjects.assets_3D.ModelType;
/**
* Visual object for a mark. Contains a coloured circle and any specified arrows.
*/
public class Marker extends Group {
private Circle mark = new Circle();
private Group mark = ModelFactory.importModel(ModelType.PLAIN_MARKER).getAssets();
private Paint colour = Color.BLACK;
private List<Group> enterArrows = new ArrayList<>();
private List<Group> exitArrows = new ArrayList<>();
@@ -24,10 +27,13 @@ public class Marker extends Group {
* Creates a new Marker containing only a circle. The default colour is black.
*/
public Marker() {
mark.setRadius(5);
mark.setCenterX(0);
mark.setCenterY(0);
Platform.runLater(() -> this.getChildren().addAll(mark, new Group())); //Empty group placeholder or arrows.
// mark.setRadius(5);
// mark.setCenterX(0);
// mark.setCenterY(0);
Platform.runLater(() -> {
mark.getTransforms().add(new Scale(5,5,5));
this.getChildren().addAll(mark, new Group());
}); //Empty group placeholder or arrows.
}
/**
@@ -37,7 +43,7 @@ public class Marker extends Group {
public Marker(Paint colour) {
this();
this.colour = colour;
mark.setFill(colour);
// mark.setFill(colour);
}
/**
@@ -48,7 +54,7 @@ public class Marker extends Group {
* @param exitAngle The angle the arrow wil point from the marker.
*/
public void addArrows(MarkArrowFactory.RoundingSide roundingSide, double entryAngle,
double exitAngle) {
double exitAngle) {
//Change Color.GRAY to this.colour to revert all gray arrows.
enterArrows.add(
MarkArrowFactory.constructEntryArrow(roundingSide, entryAngle, exitAngle, Color.GRAY)
@@ -1,4 +1,4 @@
package seng302.visualiser.fxObjects;
package seng302.visualiser.fxObjects.assets_2D;
import javafx.application.Platform;
import javafx.scene.CacheHint;
@@ -0,0 +1,25 @@
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);
}
}
@@ -0,0 +1,22 @@
package seng302.visualiser.fxObjects.assets_3D;
/**
* Enum for boat meshes. Enum values should be of the form :
* ENUM_VALUE (hull file, mast file, X offset of mast CoR from origin, sail file, X offset of sail CoR from origin)
* Files must be valid .stl files.
*/
public enum BoatMeshType {
DINGHY ("dinghy_hull.stl", "dinghy_mast.stl", -1.36653, "dinghy_sail.stl", -1.36653);
final String hullFile, mastFile, sailFile;
final double mastOffset, sailOffset;
BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile, double sailOffset) {
this.hullFile = hullFile;
this.mastFile = mastFile;
this.mastOffset = mastOffset;
this.sailFile = sailFile;
this.sailOffset = sailOffset;
}
}
@@ -0,0 +1,72 @@
package seng302.visualiser.fxObjects.assets_3D;
import javafx.animation.AnimationTimer;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.MeshView;
import javafx.scene.transform.Rotate;
/**
* Container class for a group of 3d objects representing a boat and it's animation.
*/
public class BoatModel extends Model {
private static final int HULL_INDEX = 0;
private static final int MAST_INDEX = 1;
private static final int SAIL_INDEX = 2;
private BoatMeshType meshType;
/**
* Stores a model and it's optional animation.
* @param boatAssets The group with 3d assets for the boat.
* @param animation Animation, can be null.
*/
BoatModel(Group boatAssets, AnimationTimer animation, BoatMeshType meshType) {
super(boatAssets, animation);
this.meshType = meshType;
}
/**
* Rotates the sail of this model by the given amount.
* @param degrees The rotation of the sail in degrees
*/
public void rotateSail(double degrees) {
MeshView mast = getMeshViewChild(MAST_INDEX);
MeshView sail = getMeshViewChild(SAIL_INDEX);
mast.getTransforms().setAll(
new Rotate(degrees, -meshType.mastOffset, 0,0, new Point3D(0, 0, 1))
);
sail.getTransforms().setAll(
new Rotate(degrees, -meshType.sailOffset, 0,0, new Point3D(0, 0, 1))
);
}
public void hideSail() {
getMeshViewChild(SAIL_INDEX).setVisible(false);
}
public void showSail() {
getMeshViewChild(SAIL_INDEX).setVisible(true);
}
/**
* Changes the colour of the model in this class.
* @param newColour the new colour for the boat.
*/
public void changeColour(Color newColour) {
changeColourChild(HULL_INDEX, newColour);
changeColourChild(SAIL_INDEX, newColour);
}
private void changeColourChild(int index, Color newColour) {
MeshView meshView = getMeshViewChild(index);
meshView.setMaterial(new PhongMaterial(newColour));
}
private MeshView getMeshViewChild(int index) {
return (MeshView) assets.getChildren().get(index);
}
}
@@ -0,0 +1,42 @@
package seng302.visualiser.fxObjects.assets_3D;
import javafx.animation.AnimationTimer;
import javafx.scene.Group;
/**
* Created by CJIRWIN on 7/09/2017.
*/
public class Model {
AnimationTimer animationTimer;
Group assets;
Model (Group assets, AnimationTimer animation) {
this.assets = assets;
this.animationTimer = animation;
if (animation != null) {
animation.start();
}
}
void setAnimation(AnimationTimer animation) {
animationTimer = animation;
if (animation != null) {
animation.start();
}
}
/**
* Stops the animation of this model.
*/
public void stopAnimation() {
if (animationTimer != null) {
animationTimer.stop();
animationTimer = null;
}
}
public Group getAssets() {
return this.assets;
}
}
@@ -0,0 +1,178 @@
package seng302.visualiser.fxObjects.assets_3D;
import com.interactivemesh.jfx.importer.col.ColModelImporter;
import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import javafx.animation.AnimationTimer;
import javafx.geometry.Point3D;
import javafx.scene.AmbientLight;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Circle;
import javafx.scene.shape.MeshView;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Translate;
/**
* Factory class for creating 3D models of boats.
*/
public class ModelFactory {
public static BoatModel boatIconView(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
boatAssets.getTransforms().addAll(
new Scale(20, 20, 20),
new Rotate(90, new Point3D(0,0,1)),
new Rotate(90, new Point3D(0, 1, 0))
);
boatAssets.getChildren().add(new AmbientLight(new Color(1, 1, 1, 0.01)));
return new BoatModel(boatAssets, null, boatType);
}
public static BoatModel boatRotatingView(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
boatAssets.getTransforms().addAll(
new Scale(40, 40, 40),
new Rotate(90, new Point3D(0,0,1)),
new Rotate(90, new Point3D(0, 1, 0)),
new Rotate(0, new Point3D(1,1,1))
);
// TODO: 7/09/17 This seems like it will never be garbage claimed. Might have to call BoatModel.stopAnimation();
return new BoatModel(boatAssets, new AnimationTimer() {
private double rotation = 0;
private final Group group = boatAssets;
@Override
public void handle(long now) {
rotation += 0.5;
((Rotate) group.getTransforms().get(3)).setAngle(rotation);
}
}, boatType);
}
public static BoatModel boatGameView(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
boatAssets.getTransforms().setAll(
new Rotate(-90, new Point3D(0,0,1)),
new Scale(0.05, 0.05, 0.05)
);
return new BoatModel(boatAssets, null, boatType);
}
private static Group getUnmodifiedBoatModel(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = new Group();
MeshView hull = importFile(boatType.hullFile);
hull.setMaterial(new PhongMaterial(primaryColour));
MeshView mast = importFile(boatType.mastFile);
mast.setMaterial(new PhongMaterial(primaryColour));
MeshView sail = importFile(boatType.sailFile);
sail.setMaterial(new PhongMaterial(Color.WHITE));
boatAssets.getChildren().addAll(hull, mast, sail);
return boatAssets;
}
private static MeshView importFile(String fileName) {
StlMeshImporter importer = new StlMeshImporter();
importer.read(ModelFactory.class.getResource("/meshes/" + fileName));
return new MeshView(importer.getImport());
}
public static Model importModel(ModelType tokenType) {
Group assets;
if (tokenType.filename == null) {
assets = new Group();
} else {
ColModelImporter importer = new ColModelImporter();
importer.read(ModelFactory.class.getResource("/meshes/" + tokenType.filename));
assets = new Group(importer.getImport());
}
switch (tokenType) {
case VELOCITY_PICKUP:
return makeCoinPickup(assets);
case FINISH_MARKER:
case PLAIN_MARKER:
case START_MARKER:
return makeMarker(assets);
case OCEAN:
return makeOcean(assets);
case BORDER_PYLON:
case BORDER_BARRIER:
return makeBarrier(assets);
case FINISH_LINE:
case START_LINE:
case GATE_LINE:
return makeGate(assets);
case WAKE:
return makeWake(assets);
default:
return new Model(new Group(assets), null);
}
}
private static Model makeCoinPickup(Group assets){
assets.setRotationAxis(new Point3D(1,0,0));
assets.setRotate(90);
assets.setTranslateX(0.2);
assets.setTranslateY(1);
assets.getTransforms().addAll(
new Translate(0,-1,0),
new Rotate(0 ,new Point3D(1,1,1))
);
return new Model(new Group(assets), new AnimationTimer() {
private double rotation = 0;
private Group group = assets;
@Override
public void handle(long now) {
rotation += 1;
((Rotate) group.getTransforms().get(1)).setAngle(rotation);
}
});
}
private static Model makeMarker(Group marker) {
ColModelImporter importer = new ColModelImporter();
importer.read(ModelFactory.class.getResource("/meshes/" + ModelType.MARK_AREA.filename));
Group area = new Group(importer.getImport());
area.getChildren().add(marker);
area.getTransforms().add(new Rotate(90, new Point3D(1, 0, 0)));
return new Model(new Group(area), null);
}
private static Model makeOcean(Group group) {
// group.setScaleY(Double.MAX_VALUE);
// group.setScaleX(Double.MAX_VALUE);
// group.getTransforms().add(new Rotate(90, new Point3D(1, 0, 0)));
Circle ocean = new Circle(0,0,1000, Color.DARKSEAGREEN);
ocean.setStroke(Color.TRANSPARENT);
group.getChildren().add(ocean);
return new Model(group, null);
}
private static Model makeBarrier(Group assets) {
assets.getTransforms().addAll(
new Rotate(90, new Point3D(1,0,0)),
new Scale(1.5,1.5,1.5)
);
return new Model(new Group(assets), null);
}
private static Model makeGate(Group assets) {
assets.getTransforms().addAll(
new Rotate(90, new Point3D(1,0,0))
);
return new Model(new Group(assets), null);
}
private static Model makeWake(Group assets) {
assets.getTransforms().setAll(
new Rotate(-90, new Point3D(0,0,1)),
new Rotate(90, new Point3D(1,0,0)),
new Scale(0.5, 0.5, 0.5)
);
return new Model(new Group(assets), null);
}
}
@@ -0,0 +1,28 @@
package seng302.visualiser.fxObjects.assets_3D;
/**
* Enum for models. Values should be the name of the file and files should be .dae files with texture
* information included. Can be null in which case assets are assumed to be empty.
*/
public enum ModelType {
VELOCITY_PICKUP("velocity_pickup.dae"),
FINISH_MARKER ("finish_marker.dae"),
START_MARKER ("start_marker.dae"),
PLAIN_MARKER ("plain_marker.dae"),
MARK_AREA ("mark_area.dae"),
OCEAN (null),
BORDER_PYLON ("barrier_pole.dae"),
BORDER_BARRIER ("barrier_segment.dae"),
FINISH_LINE ("finish_line.dae"),
START_LINE ("start_line.dae"),
GATE_LINE ("gate_line.dae"),
WAKE ("wake.dae");
final String filename;
ModelType(String filename) {
this.filename = filename;
}
}