Merge branch 'story1266_3d_model_factory' into NewUI_merge

This commit is contained in:
Michael Rausch
2017-09-11 23:45:31 +12:00
8 changed files with 466 additions and 108 deletions
+106 -10
View File
@@ -5,11 +5,20 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import javafx.animation.AnimationTimer;
import javafx.application.Platform;
import javafx.geometry.Point2D;
import javafx.geometry.Point3D;
import javafx.scene.*;
import javafx.scene.AmbientLight;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.effect.BlendMode;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
@@ -28,7 +37,7 @@ import seng302.model.mark.Corner;
import seng302.model.mark.Mark;
import seng302.model.token.Token;
import seng302.utilities.GeoUtility;
import seng302.visualiser.fxObjects.assets_2D.*;
import seng302.visualiser.fxObjects.assets_2D.BoatObject;
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
import seng302.visualiser.fxObjects.assets_3D.ModelType;
@@ -72,17 +81,16 @@ public class GameView3D {
private Map<Mark, Group> markerObjects;
private Map<ClientYacht, BoatObject> boatObjects = new HashMap<>();
private Map<ClientYacht, AnnotationBox> annotations = new HashMap<>();
private BoatObject selectedBoat = null;
private Group annotationsGroup = new Group();
private Group wakesGroup = new Group();
private Group boatObjectGroup = new Group();
private Group trails = new Group();
private Group markers = new Group();
private Group tokens = new Group();
private Group playerAnnotation = new Group();
private List<CompoundMark> course = new ArrayList<>();
private List<Node> mapTokens;
private Timer playerBoatAnimationTimer = new Timer();
private Group trail = new Group();
private ImageView mapImage = new ImageView();
//FRAME RATE
@@ -119,15 +127,30 @@ public class GameView3D {
camera.setNearClip(0.1);
camera.setFieldOfView(FOV);
gameObjects = new Group();
PointLight pl = new PointLight(Color.DARKGRAY);
pl.setLightOn(true);
pl.setBlendMode(BlendMode.ADD);
pl.setOpacity(0.5);
pl.getTransforms().add(new Translate(0,0,-500));
AmbientLight al = new AmbientLight();
al.setLightOn(true);
al.setBlendMode(BlendMode.SOFT_LIGHT);
al.getTransforms().add(new Translate(0, 0, -100));
root3D = new Group(camera, gameObjects);
view = new SubScene(
root3D, 1000, 1000, true, SceneAntialiasing.BALANCED
);
view.setCamera(camera);
view.setFill(Color.SKYBLUE);
// view.setFill(Color.LIGHTBLUE);
camera.getTransforms().add(new Rotate(30, new Point3D(1,0,0)));
// gameObjects.getChildren().addAll(raceBorder, markers, tokens);
System.out.println(camera.getLayoutX());
System.out.println(camera.getTranslateX());
System.out.println(camera.getLayoutY());
System.out.println(camera.getTranslateY());
System.out.println(camera.getTranslateZ());
camera.setTranslateZ(-80);
camera.setTranslateY(150);
Sphere red = new Sphere(1);
red.setMaterial(new PhongMaterial(Color.RED));
red.setLayoutX(0);
@@ -154,11 +177,16 @@ public class GameView3D {
black.setLayoutY(0);
gameObjects.getChildren().addAll(
ModelFactory.importModel(ModelType.OCEAN).getAssets(),
raceBorder, markers, tokens,
// ModelFactory.importModel(ModelType.OCEAN).getAssets(),
raceBorder, trail, markers, tokens, playerAnnotation,
white, blue, green, black, red
);
System.out.println(camera.getLayoutX());
System.out.println(camera.getTranslateX());
System.out.println(camera.getLayoutY());
System.out.println(camera.getTranslateY());
System.out.println(camera.getTranslateZ());
// Sphere s = new Sphere(1);
// s.setMaterial(new PhongMaterial(Color.RED));
// Sphere left = new Sphere(1);
@@ -639,4 +667,72 @@ public class GameView3D {
tokens.getChildren().setAll(mapTokens);
});
}
public void setBoatAsPlayer (ClientYacht playerYacht) {
this.playerYacht = playerYacht;
Platform.runLater(() ->
playerAnnotation.getChildren().setAll(ModelFactory.importModel(ModelType.PLAYER_IDENTIFIER).getAssets())
);
BoatObject playerAssets = boatObjects.get(playerYacht);
playerAnnotation.layoutXProperty().bind(playerAssets.layoutXProperty());
playerAnnotation.layoutYProperty().bind(playerAssets.layoutYProperty());
playerBoatAnimationTimer.scheduleAtFixedRate(new TimerTask() {
private Point2D lastLocation = findScaledXY(playerYacht.getLocation());
@Override
public void run() {
Node segment = ModelFactory.importModel(ModelType.TRAIL_SEGMENT).getAssets();
Point2D location = findScaledXY(playerYacht.getLocation());
segment.getTransforms().addAll(
new Translate(location.getX(), location.getY()),
new Rotate(playerYacht.getHeading(), new Point3D(0,0,1)),
new Scale(1, lastLocation.distance(location) / 5)
);
Platform.runLater(() -> {
trail.getChildren().add(segment);
if (trail.getChildren().size() > 100) {
trail.getChildren().remove(0);
}
});
lastLocation = location;
// TODO: 11/09/2017 ROTATE PLAYER ICON
// double leg = playerYacht.getLegNumber();
// if (compoundMark != null) {
// for (Mark mark : compoundMark.getMarks()) {
//// System.out.println("markerObjects.get(mark) = " + markerObjects.get(mark));
// markerObjects.get(mark).showNextExitArrow();
// }
// }
// CompoundMark nextMark = null;
// if (legNumber < course.size() - 1) {
// nextMark = course.get(legNumber);
// for (Mark mark : nextMark.getMarks()) {
// markerObjects.get(mark).showNextEnterArrow();
// }
// }
}
}, 0L, 500L);
// playerYacht.toggleSail();
// boatObjects.get(playerYacht).setAsPlayer();
// CompoundMark currentMark = course.get(playerYacht.getLegNumber());
// for (Mark mark : currentMark.getMarks()) {
// markerObjects.get(mark).showNextExitArrow();
// }
// annotations.get(playerYacht).addAnnotation(
// "velocity",
// playerYacht.getVelocityProperty(),
// (velocity) -> String.format("Speed: %.2f ms", velocity.doubleValue())
// );
// Platform.runLater(() -> {
// boatObjectGroup.getChildren().remove(boatObjects.get(playerYacht));
// gameObjects.add(boatObjects.get(playerYacht));
// annotationsGroup.getChildren().remove(annotations.get(playerYacht));
// gameObjects.add(annotations.get(playerYacht));
// });
// playerYacht.addMarkRoundingListener(this::updateMarkArrows);
}
}
@@ -194,21 +194,21 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
new ArrayList<>(raceData.getCompoundMarks().values()), raceData.getMarkSequence()
);
// gameView.enableZoom();
// gameView.setBoatAsPlayer(player);
gameView.setBoatAsPlayer(player);
// gameView.startRace();
// raceState.addCollisionListener(gameView::drawCollision);
// raceState.windDirectionProperty().addListener((obs, oldDirection, newDirection) -> {
raceState.windDirectionProperty().addListener((obs, oldDirection, newDirection) -> {
// gameView.setWindDir(newDirection.doubleValue());
// Platform.runLater(() -> updateWindDirection(newDirection.doubleValue()));
// });
Platform.runLater(() -> updateWindDirection(newDirection.doubleValue()));
});
// raceState.windSpeedProperty().addListener((obs, oldSpeed, newSpeed) ->
// Platform.runLater(() -> updateWindSpeed(newSpeed.doubleValue()))
// );
// Platform.runLater(() -> {
// updateWindDirection(raceState.windDirectionProperty().doubleValue());
// updateWindSpeed(raceState.getWindSpeed());
// });
Platform.runLater(() -> {
updateWindDirection(raceState.windDirectionProperty().doubleValue());
updateWindSpeed(raceState.getWindSpeed());
});
// gameView.setWindDir(raceState.windDirectionProperty().doubleValue());
//TODO extract chat stuff
@@ -1,6 +1,8 @@
package seng302.visualiser.fxObjects.assets_2D;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.geometry.Point2D;
import javafx.geometry.Point3D;
import javafx.scene.AmbientLight;
@@ -61,8 +63,7 @@ public class BoatObject extends Group {
private double sailState;
//Graphical objects
private Polyline trail = new Polyline();
// private Polygon boatPoly;
private BoatModel boatPoly;
private BoatModel boatAssets;
private Polygon sail;
private Group wake;
private Line leftLayLine;
@@ -103,31 +104,32 @@ public class BoatObject extends Group {
* polygon.
*/
private void initChildren(double... points) {
boatPoly = makeBoatPolygon();
boatPoly.getAssets().getTransforms().addAll(
boatAssets = ModelFactory.boatGameView(BoatMeshType.DINGHY, colour);
boatAssets.hideSail();
boatAssets.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));
boatAssets.getAssets().getTransforms().add(new Scale(5, 5, 5));
// boatAssets.setDrawMode(DrawMode.FILL);
// boatAssets.setFill(colour);
// boatAssets.setFill(this.colour);
// boatAssets.setMaterial(new PhongMaterial(this.colour));
boatAssets.getAssets().setOnMouseEntered(event -> {
// boatAssets.setFill(Color.FLORALWHITE);
// boatAssets.setStroke(Color.RED);
// boatAssets.setMaterial(new PhongMaterial(Color.FLORALWHITE));
});
boatPoly.getAssets().setOnMouseExited(event -> {
// boatPoly.setMaterial(new PhongMaterial(this.colour));
// boatPoly.setFill(colour);
// boatPoly.setFill(this.colour);
// boatPoly.setStroke(Color.BLACK);
boatAssets.getAssets().setOnMouseExited(event -> {
// boatAssets.setMaterial(new PhongMaterial(this.colour));
// boatAssets.setFill(colour);
// boatAssets.setFill(this.colour);
// boatAssets.setStroke(Color.BLACK);
});
boatPoly.getAssets().setOnMouseClicked(event -> setIsSelected(!isSelected));
boatPoly.getAssets().setCache(true);
// boatPoly.setCacheHint(CacheHint.SPEED);
boatAssets.getAssets().setOnMouseClicked(event -> setIsSelected(!isSelected));
boatAssets.getAssets().setCache(true);
// boatAssets.setCacheHint(CacheHint.SPEED);
// annotationBox = new AnnotationBox();
// annotationBox.setFill(colour);
@@ -165,46 +167,21 @@ public class BoatObject extends Group {
// 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());
super.getChildren().addAll(boatAssets.getAssets());
}
public void setFill (Color value) {
this.colour = value;
PhongMaterial pm = new PhongMaterial(this.colour);
pm.setSpecularPower(0.5);
pm.setSpecularColor(Color.BLACK);
for (int i=0;i<2;i++) {
Shape3D s = (Shape3D) boatPoly.getAssets().getChildren().get(i);
Shape3D s = (Shape3D) boatAssets.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
@@ -216,12 +193,12 @@ 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.getAssets().getLayoutX() - x);
Double dy = Math.abs(boatPoly.getAssets().getLayoutY() - y);
Double dx = Math.abs(boatAssets.getAssets().getLayoutX() - x);
Double dy = Math.abs(boatAssets.getAssets().getLayoutY() - y);
Platform.runLater(() -> {
rotateTo(rotation, sailIn, windDir);
boatPoly.getAssets().setLayoutX(x);
boatPoly.getAssets().setLayoutY(y);
boatAssets.getAssets().setLayoutX(x);
boatAssets.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);
@@ -238,8 +215,8 @@ public class BoatObject extends Group {
});
// wake.setRotation(rotation, velocity);
// rotateTo(rotation);
// boatPoly.setLayoutX(x);
// boatPoly.setLayoutY(y);
// boatAssets.setLayoutX(x);
// boatAssets.setLayoutY(y);
// wake.setLayoutX(x);
// wake.setLayoutY(y);
// wake.rotate(rotation);
@@ -267,31 +244,32 @@ public class BoatObject extends Group {
private void rotateTo(double heading, boolean sailsIn, double windDir) {
rotation.setAngle(heading);
wake.getTransforms().setAll(new Rotate(heading, new Point3D(0,0,1)));
if (!sailsIn) {
boatPoly.showSail();
if (sailsIn) {
boatAssets.showSail();
System.out.println("heading = " + heading);
Double sailWindOffset = 30.0;
Double upwindAngleLimit = 15.0;
Double downwindAngleLimit = 10.0; //Upwind from normalised horizontal
Double normalizedHeading = normalizeHeading(heading, windDir);
if (normalizedHeading < 180) {
if (normalizedHeading < sailWindOffset + upwindAngleLimit){
boatPoly.rotateSail(90 - upwindAngleLimit);
boatAssets.rotateSail(-heading + 90 - upwindAngleLimit);
} else if (normalizedHeading > 90 + sailWindOffset){
boatPoly.rotateSail(downwindAngleLimit);
boatAssets.rotateSail(-heading + downwindAngleLimit);
} else {
boatPoly.rotateSail(90 + sailWindOffset);
boatAssets.rotateSail(-heading + 90 + sailWindOffset);
}
} else {
if (normalizedHeading > 360 - (sailWindOffset + upwindAngleLimit)){
boatPoly.rotateSail(90 + upwindAngleLimit);
} else if (normalizedHeading < 270 - sailWindOffset){
boatPoly.rotateSail(180 - downwindAngleLimit);
} else {
boatPoly.rotateSail(90 - sailWindOffset);
}
// if (normalizedHeading > 360 - (sailWindOffset + upwindAngleLimit)){
// boatAssets.rotateSail(-heading + 90 + upwindAngleLimit);
// } else if (normalizedHeading < 270 - sailWindOffset){
// boatAssets.rotateSail(-heading + 180 - downwindAngleLimit);
// } else {
// boatAssets.rotateSail(-heading + 90 - sailWindOffset);
// }
}
} else {
boatPoly.hideSail();
boatAssets.hideSail();
}
}
@@ -317,7 +295,7 @@ public class BoatObject extends Group {
}
public void updateLocation() {
// boatPoly.getTransforms().add(new Rotate(2, new Point3D(1,1,1)));
// boatAssets.getTransforms().add(new Rotate(2, new Point3D(1,1,1)));
// double dx = xVelocity / 60;
// double dy = yVelocity / 60;
//
@@ -331,8 +309,8 @@ public class BoatObject extends Group {
// Line l = new Line(
// lastPoint.getX(),
// lastPoint.getY(),
// boatPoly.getLayoutX(),
// boatPoly.getLayoutY()
// boatAssets.getLayoutX(),
// boatAssets.getLayoutY()
// );
// l.getStrokeDashArray().setAll(3d, 7d);
// l.setStroke(colour);
@@ -340,7 +318,7 @@ public class BoatObject extends Group {
// l.setCacheHint(CacheHint.SPEED);
// lineGroup.getChildren().add(l);
// }
// lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
// lastPoint = new Point2D(boatAssets.getLayoutX(), boatAssets.getLayoutY());
// }
// wake.updatePosition();
}
@@ -361,7 +339,7 @@ public class BoatObject extends Group {
// Point2D nextMarkPoint1 = canvasController.findScaledXY(nextMark1.getLatitude(), nextMark1.getLongitude());
// Point2D nextMarkPoint2 = canvasController.findScaledXY(nextMark2.getLatitude(), nextMark2.getLongitude());
//
// Point2D boatCurrentPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
// Point2D boatCurrentPoint = new Point2D(boatAssets.getLayoutX(), boatAssets.getLayoutY());
// Point2D windTestPoint = GeoUtility.makeArbitraryVectorPoint(nextMarkPoint1, windAngle, 10d);
//
//
@@ -427,26 +405,26 @@ public class BoatObject extends Group {
}
public Double getBoatLayoutX() {
return boatPoly.getAssets().getLayoutX();
return boatAssets.getAssets().getLayoutX();
}
public Double getBoatLayoutY() {
return boatPoly.getAssets().getLayoutY();
return boatAssets.getAssets().getLayoutY();
}
/**
* Sets this boat to appear highlighted
*/
public void setAsPlayer() {
// boatPoly.getPoints().setAll(
// boatAssets.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);
// boatAssets.setStroke(Color.BLACK);
// boatAssets.setStrokeWidth(2);
// boatAssets.setStrokeLineCap(StrokeLineCap.ROUND);
isPlayer = true;
animateSail();
}
@@ -5,10 +5,10 @@ import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import javafx.animation.AnimationTimer;
import javafx.geometry.Point3D;
import javafx.scene.AmbientLight;
import javafx.scene.CacheHint;
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;
@@ -56,7 +56,7 @@ public class ModelFactory {
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
boatAssets.getTransforms().setAll(
new Rotate(-90, new Point3D(0,0,1)),
new Scale(0.05, 0.05, 0.05)
new Scale(0.06, 0.06, 0.06)
);
return new BoatModel(boatAssets, null, boatType);
}
@@ -76,6 +76,9 @@ public class ModelFactory {
private static MeshView importFile(String fileName) {
StlMeshImporter importer = new StlMeshImporter();
importer.read(ModelFactory.class.getResource("/meshes/" + fileName));
MeshView importedFile = new MeshView(importer.getImport());
importedFile.setCache(true);
importedFile.setCacheHint(CacheHint.SCALE_AND_ROTATE);
return new MeshView(importer.getImport());
}
@@ -87,6 +90,8 @@ public class ModelFactory {
ColModelImporter importer = new ColModelImporter();
importer.read(ModelFactory.class.getResource("/meshes/" + tokenType.filename));
assets = new Group(importer.getImport());
assets.setCache(true);
assets.setCacheHint(CacheHint.SCALE_AND_ROTATE);
}
switch (tokenType) {
case VELOCITY_PICKUP:
@@ -106,6 +111,10 @@ public class ModelFactory {
return makeGate(assets);
case WAKE:
return makeWake(assets);
case TRAIL_SEGMENT:
return makeTrail(assets);
case PLAYER_IDENTIFIER:
return makeIdentifierIcon(assets);
default:
return new Model(new Group(assets), null);
}
@@ -145,11 +154,15 @@ public class ModelFactory {
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);
group.getTransforms().addAll(
new Rotate(90, new Point3D(1, 0, 0)),
new Scale(10,4,10)
);
// group.getChildren().add(new AmbientLight());
// Circle ocean = new Circle(0,0,500, Color.SKYBLUE);
// ocean.setStroke(Color.TRANSPARENT);
// group.getChildren().add(ocean);
return new Model(new Group(group), null);
}
private static Model makeBarrier(Group assets) {
@@ -175,4 +188,19 @@ public class ModelFactory {
);
return new Model(new Group(assets), null);
}
private static Model makeTrail(Group trailPiece) {
trailPiece.getTransforms().addAll(
new Rotate(90, new Point3D(0,0,1))
);
return new Model(new Group(trailPiece), null);
}
private static Model makeIdentifierIcon(Group assets) {
assets.getTransforms().addAll(
new Rotate(90, new Point3D(1,0,0)),
new Scale(0.5, 0.5, 0.5)
);
return new Model(assets, null);
}
}
@@ -11,13 +11,15 @@ public enum ModelType {
START_MARKER ("start_marker.dae"),
PLAIN_MARKER ("plain_marker.dae"),
MARK_AREA ("mark_area.dae"),
OCEAN (null),
OCEAN ("ocean.dae"),
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");
WAKE ("wake.dae"),
TRAIL_SEGMENT ("trail_segment.dae"),
PLAYER_IDENTIFIER ("player_identifier.dae");
final String filename;