mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e93be7b36 | |||
| 191b818e38 | |||
| 19db6668da | |||
| 44275aec04 | |||
| 64245833cd | |||
| aa0149b9a7 | |||
| f6b41f0513 | |||
| 8dfdb228e9 | |||
| 1042817e4e | |||
| 066557584f | |||
| 4011295b8b | |||
| 0a885dd8fd | |||
| e9b50038a9 | |||
| 364264377a | |||
| 9112183ac3 | |||
| 957821f1f2 | |||
| 094eb4c1cf | |||
| 607acff7c6 | |||
| 22fdf1e4ac | |||
| da8c91f5c1 | |||
| 52dc7a956d | |||
| 9f64b2380d | |||
| b05580f018 | |||
| c20c6fb264 | |||
| faeece27ff | |||
| c4a6113f6c | |||
| 307e79ecfc | |||
| 7d8a6afa5f | |||
| ea0be5e952 | |||
| 7197bc2bee | |||
| fba522d0c3 | |||
| 0e829874c2 | |||
| c5d56065b6 | |||
| 410d765745 | |||
| fe76e85c71 | |||
| 9d61a43bd7 | |||
| d4d7ddf8e2 | |||
| a1933c2869 | |||
| 8084a61333 | |||
| 03f5f91043 | |||
| 9ed52a1225 | |||
| 027324cc4f |
@@ -10,13 +10,11 @@ import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.discoveryServer.DiscoveryServer;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(App.class);
|
||||
private static boolean isRunningAsCache = false;
|
||||
|
||||
public static void parseArgs(String[] args) throws ParseException {
|
||||
Options options = new Options();
|
||||
@@ -27,21 +25,9 @@ public class App extends Application {
|
||||
.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
|
||||
options.addOption("debugLevel", true, "Set the application debug level");
|
||||
options.addOption("runAsDiscoveryServer", false, "Run as a discovery server");
|
||||
options.addOption("discoveryDevMode", false, "Use a local discovery server");
|
||||
|
||||
cmd = parser.parse(options, args);
|
||||
|
||||
if (cmd.hasOption("runAsDiscoveryServer")){
|
||||
isRunningAsCache = true;
|
||||
rootLogger.setLevel(Level.ALL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.hasOption("discoveryDevMode")) {
|
||||
DiscoveryServer.DISCOVERY_SERVER = "localhost";
|
||||
}
|
||||
|
||||
if (cmd.hasOption("debugLevel")) {
|
||||
|
||||
switch (cmd.getOptionValue("debugLevel")) {
|
||||
@@ -81,20 +67,15 @@ public class App extends Application {
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
parseArgs(args);
|
||||
} catch (ParseException e) {
|
||||
logger.error("Could not parse command line arguments");
|
||||
}
|
||||
|
||||
if (!isRunningAsCache){
|
||||
launch(args);
|
||||
}
|
||||
else{
|
||||
new DiscoveryServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
package seng302.discoveryServer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.gameServer.messages.Message;
|
||||
import seng302.gameServer.messages.RoomCodeRequest;
|
||||
import seng302.gameServer.messages.ServerRegistrationMessage;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
||||
import seng302.discoveryServer.util.ServerTable;
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
public class DiscoveryServer {
|
||||
public static final String ANSI_GREEN = "\u001B[32m";
|
||||
public static final String ANSI_YELLOW = "\u001B[33m";
|
||||
public static final String ANSI_BLUE = "\u001B[34m";
|
||||
public static final String ANSI_RESET = "\u001B[0m";
|
||||
public static String DISCOVERY_SERVER = "party.sydney.srv.michaelrausch.nz";
|
||||
|
||||
private ServerTable serverTable;
|
||||
public static final Integer PORT_NUMBER = 9969;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(DiscoveryServer.class);
|
||||
|
||||
private void displayHeader(){
|
||||
String selectedColor = Arrays.asList(ANSI_BLUE, ANSI_GREEN, ANSI_YELLOW).get(new Random().nextInt(2));
|
||||
System.out.println(selectedColor);
|
||||
System.out.println(" .ccccc. \n" +
|
||||
" .cc;'coooxkl;. \n" +
|
||||
" .:c:::c:,,,,,;c;;,.'. \n" +
|
||||
" .clc,',:,..:xxocc;'..c; \n" +
|
||||
" .c:,';:ox:..:c,,,,,,...cd, \n" +
|
||||
" .c:'.,oxxxxl::l:.,loll;..;ol. \n" +
|
||||
" ;Oc..:xxxxxxxxx:.,llll,....oc \n" +
|
||||
" .,;,',:loxxxxxxxxx:.,llll;.,,.'ld, \n" +
|
||||
" .lo;..:xxxxxxxxxxxx:.'cllc,.:l:'cO; \n" +
|
||||
" .:;...'cxxxxxxxxxxxxoc;,::,..cdl;;l' \n" +
|
||||
" .cl;':,'';oxxxxxxdxxxxxx:....,cooc,cO; \n" +
|
||||
" .,,,::;,lxoc:,,:lxxxxxxxxxxxo:,,;lxxl;'oNc \n" +
|
||||
" .cdxo;':lxxxxxxc'';cccccoxxxxxxxxxxxxo,.;lc. " + ANSI_YELLOW + "Party-Parrots-At-Sea Discovery Server v0.1 " + selectedColor +"\n" +
|
||||
" .loc'.'lxxxxxxxxocc;''''';ccoxxxxxxxxx:..oc \n" +
|
||||
"olc,..',:cccccccccccc:;;;;;;;;:ccccccccc,.'c, \n" +
|
||||
"Ol;......................................;l' ");
|
||||
System.out.println(ANSI_RESET);
|
||||
}
|
||||
|
||||
public DiscoveryServer() throws Exception {
|
||||
displayHeader();
|
||||
serverTable = new ServerTable();
|
||||
|
||||
ServerSocket serverSocket;
|
||||
|
||||
try{
|
||||
serverSocket = new ServerSocket(PORT_NUMBER);
|
||||
}
|
||||
catch(java.net.BindException e){
|
||||
logger.error("FATAL - Could not bind socket, are you sure there isn't already an instance running?");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Started successfully - Now accepting connections");
|
||||
|
||||
while (true){
|
||||
Socket clientSocket = serverSocket.accept();
|
||||
|
||||
parseRequest(clientSocket);
|
||||
|
||||
clientSocket.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseRequest(Socket clientSocket) throws Exception {
|
||||
ServerRepoStreamParser parser = new ServerRepoStreamParser(clientSocket.getInputStream());
|
||||
|
||||
if (clientSocket.isConnected() && !clientSocket.isClosed()){
|
||||
PacketType parsePacketResult = parser.parse();
|
||||
|
||||
switch (parsePacketResult){
|
||||
case SERVER_REGISTRATION:
|
||||
ServerListing listing = parser.getServerListing();
|
||||
|
||||
if (!serverTable.getAllServers().contains(listing)){
|
||||
listing.setRoomCode(serverTable.getNextRoomCode().toString());
|
||||
}
|
||||
|
||||
serverTable.addServer(listing);
|
||||
|
||||
Message serverRegMessage = new RoomCodeRequest(listing.getRoomCode());
|
||||
clientSocket.getOutputStream().write(serverRegMessage.getBuffer());
|
||||
break;
|
||||
|
||||
case ROOM_CODE_REQUEST:
|
||||
String desiredRoomCode = parser.getRoomCode();
|
||||
|
||||
ServerListing serverListing = serverTable.getServerByRoomCode(desiredRoomCode);
|
||||
Message response;
|
||||
|
||||
if (serverListing != null){
|
||||
response = new ServerRegistrationMessage(serverListing.getServerName(), serverListing.getMapName(), serverListing.getAddress(), serverListing.getPortNumber(), 0, 0, desiredRoomCode);
|
||||
}
|
||||
else{
|
||||
response = new ServerRegistrationMessage("", "", "", 0, 0, 0, "");
|
||||
}
|
||||
|
||||
clientSocket.getOutputStream().write(response.getBuffer());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package seng302.discoveryServer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.gameServer.messages.Message;
|
||||
import seng302.gameServer.messages.RoomCodeRequest;
|
||||
import seng302.gameServer.messages.ServerRegistrationMessage;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DiscoveryServerClient {
|
||||
private final Integer UPDATE_INTERVAL_MS = 5000;
|
||||
|
||||
private static String roomCode = null;
|
||||
private Timer serverListingUpdateTimer;
|
||||
private Logger logger = LoggerFactory.getLogger(DiscoveryServerClient.class);
|
||||
|
||||
public DiscoveryServerClient() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the server with the discovery server
|
||||
* @param serverListing The listing to register
|
||||
*/
|
||||
public void register(ServerListing serverListing){
|
||||
if (serverListingUpdateTimer != null){
|
||||
serverListingUpdateTimer.cancel();
|
||||
serverListingUpdateTimer = null;
|
||||
}
|
||||
|
||||
serverListingUpdateTimer = new Timer();
|
||||
|
||||
serverListingUpdateTimer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
sendRegistrationUpdate(serverListing);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Could not update server listing");
|
||||
}
|
||||
}
|
||||
}, 0, UPDATE_INTERVAL_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop updating the server registration updates
|
||||
*/
|
||||
public void unregister(){
|
||||
serverListingUpdateTimer.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the connection information for a server given a room code
|
||||
*
|
||||
* @param roomCode The room code to search for
|
||||
* @return The ServerListing, or null if there was an error
|
||||
* @throws Exception .
|
||||
*/
|
||||
public ServerListing getServerForRoomCode(String roomCode) throws Exception {
|
||||
Socket socket = new Socket(DiscoveryServer.DISCOVERY_SERVER, DiscoveryServer.PORT_NUMBER);
|
||||
ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream());
|
||||
|
||||
Message request = new RoomCodeRequest(roomCode); //roomCode);
|
||||
socket.getOutputStream().write(request.getBuffer());
|
||||
|
||||
PacketType packetType = parser.parse();
|
||||
|
||||
if (packetType != PacketType.SERVER_REGISTRATION){
|
||||
logger.debug("Wrong packet received in response to a room code request");
|
||||
return null;
|
||||
}
|
||||
|
||||
socket.close();
|
||||
|
||||
return parser.getServerListing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a registration update to the discovery server.
|
||||
*
|
||||
* @param serverListing The server listing to send
|
||||
* @throws Exception IF there was an error sending the update
|
||||
*/
|
||||
private void sendRegistrationUpdate(ServerListing serverListing) throws Exception {
|
||||
Socket socket = new Socket(DiscoveryServer.DISCOVERY_SERVER, DiscoveryServer.PORT_NUMBER);
|
||||
ServerRepoStreamParser parser = new ServerRepoStreamParser(socket.getInputStream());
|
||||
|
||||
Message req = new ServerRegistrationMessage(serverListing);
|
||||
|
||||
socket.getOutputStream().write(req.getBuffer());
|
||||
|
||||
PacketType packetType = parser.parse();
|
||||
|
||||
if (packetType != PacketType.ROOM_CODE_REQUEST){
|
||||
socket.close();
|
||||
return;
|
||||
}
|
||||
|
||||
String roomCode = parser.getRoomCode();
|
||||
|
||||
if (roomCode.length() != 0){
|
||||
DiscoveryServerClient.roomCode = roomCode;
|
||||
}
|
||||
|
||||
socket.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The last room code received by the client
|
||||
*/
|
||||
public static String getRoomCode(){
|
||||
return roomCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package seng302.discoveryServer.util;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ReadableByteInputStream {
|
||||
private InputStream is;
|
||||
|
||||
public ReadableByteInputStream(InputStream is){
|
||||
this.is = is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get n bytes from the input stream
|
||||
* @param n number of bytes
|
||||
* @return the bytes read
|
||||
* @throws Exception .
|
||||
*/
|
||||
public byte[] getBytes(int n) throws Exception {
|
||||
byte[] bytes = new byte[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
bytes[i] = (byte) readByte();
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip n bytes
|
||||
* @param n number of bytes to skip
|
||||
* @throws Exception
|
||||
*/
|
||||
public void skipBytes(long n) throws Exception {
|
||||
for (int i = 0; i < n; i++) {
|
||||
readByte();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next byte from the stream
|
||||
* @return The byte that was read
|
||||
* @throws Exception .
|
||||
*/
|
||||
public int readByte() throws Exception {
|
||||
int currentByte = is.read();
|
||||
|
||||
if (currentByte == -1) {
|
||||
throw new Exception();
|
||||
}
|
||||
return currentByte;
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package seng302.discoveryServer.util;
|
||||
|
||||
public class ServerListing {
|
||||
public final static int SERVER_TTL_DEFAULT = 10;
|
||||
|
||||
private String serverName = "";
|
||||
private String mapName = "";
|
||||
private String address = "";
|
||||
private int portNumber = 0;
|
||||
private int capacity = 0;
|
||||
private int players = 0;
|
||||
private String roomCode = "";
|
||||
private int ttl = SERVER_TTL_DEFAULT;
|
||||
|
||||
|
||||
public ServerListing(String serverName, String mapName, String address, int portNumber, int capacity){
|
||||
this.serverName = serverName;
|
||||
this.mapName = mapName;
|
||||
this.address = address;
|
||||
this.portNumber = portNumber;
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public ServerListing setNumberOfPlayers(int players){
|
||||
this.players = players;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerListing setRoomCode(String roomCode){
|
||||
this.roomCode = roomCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void refreshTtl(){
|
||||
ttl = SERVER_TTL_DEFAULT;
|
||||
}
|
||||
|
||||
public void decrementTtl(){
|
||||
ttl--;
|
||||
}
|
||||
|
||||
public boolean hasTtlExpired(){
|
||||
return ttl < 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!ServerListing.class.isAssignableFrom(obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ServerListing other = (ServerListing) obj;
|
||||
|
||||
if (this.getPortNumber() != other.getPortNumber()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.getMapName().equals(other.getMapName())){
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.getServerName().equals(other.getServerName())){
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getCapacity() != other.getCapacity()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.getAddress().equals(other.getAddress())){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.getServerName().hashCode() +
|
||||
this.getAddress().hashCode() + this.getMapName().hashCode();
|
||||
}
|
||||
|
||||
public String getRoomCode() {
|
||||
return roomCode;
|
||||
}
|
||||
|
||||
public int getPortNumber() {
|
||||
return portNumber;
|
||||
}
|
||||
|
||||
public String getMapName() {
|
||||
return mapName;
|
||||
}
|
||||
|
||||
public String getServerName() {
|
||||
return serverName;
|
||||
}
|
||||
|
||||
public int getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setTtl(Integer ttl){
|
||||
this.ttl = ttl;
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
package seng302.discoveryServer.util;
|
||||
|
||||
|
||||
import seng302.gameServer.messages.Message;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ServerRepoStreamParser {
|
||||
private ReadableByteInputStream inputStream;
|
||||
|
||||
private String roomCode;
|
||||
private String mapName;
|
||||
private ServerListing serverListing;
|
||||
|
||||
public ServerRepoStreamParser(InputStream is){
|
||||
inputStream = new ReadableByteInputStream(is);
|
||||
}
|
||||
|
||||
public PacketType parse() throws Exception {
|
||||
int sync1 = inputStream.readByte();
|
||||
int sync2 = inputStream.readByte();
|
||||
|
||||
PacketType packetType = null;
|
||||
|
||||
if (sync1 == 0x47 && sync2 == 0x83) {
|
||||
int type = inputStream.readByte();
|
||||
inputStream.skipBytes(10);
|
||||
long payloadLength = Message.bytesToLong(inputStream.getBytes(2));
|
||||
byte[] payload = inputStream.getBytes((int) payloadLength);
|
||||
inputStream.skipBytes(4);
|
||||
|
||||
packetType = PacketType.assignPacketType(type, payload);
|
||||
|
||||
switch (packetType) {
|
||||
case ROOM_CODE_REQUEST:
|
||||
roomCode = parseRoomCodeRequest(payload);
|
||||
break;
|
||||
|
||||
case LOBBY_REQUEST:
|
||||
mapName = parseLobbyRequest(payload);
|
||||
|
||||
case SERVER_REGISTRATION:
|
||||
serverListing = parseServerRegistration(payload);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return packetType;
|
||||
}
|
||||
private String parseLobbyRequest(byte[] payload) {
|
||||
int mapNameLength = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 0 ,4));
|
||||
|
||||
return new String(Arrays.copyOfRange(payload, 4, 4+mapNameLength));
|
||||
}
|
||||
|
||||
private String parseRoomCodeRequest(byte[] payload) {
|
||||
int roomCodeLength = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 0 ,6));
|
||||
|
||||
return new String(Arrays.copyOfRange(payload, 6, 6+roomCodeLength));
|
||||
}
|
||||
|
||||
public static ServerListing parseServerRegistration(byte[] payload) {
|
||||
int nameLength = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 0, 6));
|
||||
int mapNameLength = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 6, 12));
|
||||
int addressLength = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 12, 18));
|
||||
int roomCodeLength = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 18, 24));
|
||||
|
||||
int portNumber = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 24, 28));
|
||||
int players = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 28, 32));
|
||||
int capacity = (int) Message.bytesToLong(Arrays.copyOfRange(payload, 32, 36));
|
||||
|
||||
int currentPos = 36;
|
||||
int nextPos = currentPos + nameLength;
|
||||
String serverName = new String(Arrays.copyOfRange(payload, currentPos, nextPos));
|
||||
|
||||
currentPos = nextPos;
|
||||
nextPos = currentPos + mapNameLength;
|
||||
String mapName = new String(Arrays.copyOfRange(payload, currentPos, nextPos));
|
||||
|
||||
currentPos = nextPos;
|
||||
nextPos = currentPos + addressLength;
|
||||
String address = new String(Arrays.copyOfRange(payload, currentPos, nextPos));
|
||||
|
||||
currentPos = nextPos;
|
||||
nextPos = currentPos + roomCodeLength;
|
||||
String roomCode = new String(Arrays.copyOfRange(payload, currentPos, nextPos));
|
||||
|
||||
ServerListing serverListing = new ServerListing(serverName, mapName, address, portNumber, capacity);
|
||||
serverListing.setNumberOfPlayers(players);
|
||||
serverListing.setRoomCode(roomCode);
|
||||
|
||||
return serverListing;
|
||||
}
|
||||
|
||||
public String getRoomCode() {
|
||||
return roomCode;
|
||||
}
|
||||
|
||||
public String getMapName() {
|
||||
return mapName;
|
||||
}
|
||||
|
||||
public ServerListing getServerListing() {
|
||||
return serverListing;
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package seng302.discoveryServer.util;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ServerTable {
|
||||
private List<ServerListing> servers;
|
||||
private int lastRoomCode = 4020;
|
||||
private Logger logger = LoggerFactory.getLogger(ServerTable.class);
|
||||
|
||||
public ServerTable(){
|
||||
servers = new ArrayList<>();
|
||||
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateServers();
|
||||
}
|
||||
}, 0, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the servers TTL values, and then remove expired servers
|
||||
*/
|
||||
private void updateServers() {
|
||||
List<ServerListing> serversToRemove = new ArrayList<>();
|
||||
|
||||
for (ServerListing server : servers){
|
||||
server.decrementTtl();
|
||||
|
||||
if (server.hasTtlExpired()){
|
||||
logger.debug("Removed expired server - " + server.getServerName());
|
||||
serversToRemove.add(server);
|
||||
}
|
||||
}
|
||||
|
||||
servers.removeAll(serversToRemove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a server to the table
|
||||
* @param server The server to add
|
||||
*/
|
||||
public void addServer(ServerListing server){
|
||||
if (servers.contains(server)){
|
||||
updateTtlForServer(server);
|
||||
return;
|
||||
}
|
||||
logger.debug("Added new server - " + server.getServerName());
|
||||
servers.add(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the TTL for a given server to the default TTL value
|
||||
* @param server The server to update
|
||||
*/
|
||||
private void updateTtlForServer(ServerListing server) {
|
||||
for (ServerListing serverListing : servers){
|
||||
if (server.equals(serverListing)){
|
||||
serverListing.refreshTtl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All the servers in the table
|
||||
*/
|
||||
public List<ServerListing> getAllServers(){
|
||||
return Collections.unmodifiableList(servers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a server from the table given its room code
|
||||
* @param roomCode The room code to search for
|
||||
* @return The ServerListing of the found server, or null
|
||||
* the server wasn't found
|
||||
*/
|
||||
public ServerListing getServerByRoomCode(String roomCode){
|
||||
for (ServerListing serverListing : servers){
|
||||
if (serverListing.getRoomCode().equals(roomCode)){
|
||||
return serverListing;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The next available room code
|
||||
*/
|
||||
public Integer getNextRoomCode(){
|
||||
lastRoomCode += 1;
|
||||
return lastRoomCode;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,35 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import javafx.scene.paint.Color;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
import seng302.gameServer.messages.*;
|
||||
import seng302.model.*;
|
||||
import seng302.gameServer.messages.BoatAction;
|
||||
import seng302.gameServer.messages.BoatStatus;
|
||||
import seng302.gameServer.messages.ChatterMessage;
|
||||
import seng302.gameServer.messages.CustomizeRequestType;
|
||||
import seng302.gameServer.messages.MarkRoundingMessage;
|
||||
import seng302.gameServer.messages.MarkType;
|
||||
import seng302.gameServer.messages.Message;
|
||||
import seng302.gameServer.messages.RoundingBoatStatus;
|
||||
import seng302.gameServer.messages.YachtEventCodeMessage;
|
||||
import seng302.gameServer.messages.YachtEventType;
|
||||
import seng302.model.GeoPoint;
|
||||
import seng302.model.Limit;
|
||||
import seng302.model.Player;
|
||||
import seng302.model.PolarTable;
|
||||
import seng302.model.ServerYacht;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.mark.MarkOrder;
|
||||
@@ -14,10 +37,7 @@ import seng302.model.token.Token;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.utilities.XMLParser;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.util.*;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* A Static class to hold information about the current state of the game (model)
|
||||
@@ -47,7 +67,6 @@ public class GameState implements Runnable {
|
||||
private static final Double BOUNCE_DISTANCE_MARK = 20.0;
|
||||
public static final Double BOUNCE_DISTANCE_YACHT = 30.0;
|
||||
private static final Double COLLISION_VELOCITY_PENALTY = 0.3;
|
||||
private static final Integer VELOCITY_BOOST_MULTIPLIER = 2;
|
||||
|
||||
private static Long previousUpdateTime;
|
||||
public static Double windDirection;
|
||||
@@ -272,6 +291,12 @@ public class GameState implements Runnable {
|
||||
case DOWNWIND:
|
||||
playerYacht.turnDownwind();
|
||||
break;
|
||||
case CONTINUOUSLY_TURNING:
|
||||
playerYacht.setContinuouslyTurning(true);
|
||||
break;
|
||||
case DEFAULT_TURNING:
|
||||
playerYacht.setContinuouslyTurning(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,12 +307,7 @@ public class GameState implements Runnable {
|
||||
public static void spawnNewToken() {
|
||||
Random random = new Random();
|
||||
tokensInPlay.clear();
|
||||
|
||||
//Get a random token location with random type
|
||||
Token token = allTokens.get(random.nextInt(allTokens.size()));
|
||||
token.assignRandomType();
|
||||
|
||||
tokensInPlay.add(token);
|
||||
tokensInPlay.add(allTokens.get(random.nextInt(allTokens.size())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -388,7 +408,6 @@ public class GameState implements Runnable {
|
||||
//Yacht Collision
|
||||
ServerYacht collidedYacht = checkYachtCollision(serverYacht);
|
||||
Mark collidedMark = checkMarkCollision(serverYacht);
|
||||
Token collidedToken = checkTokenPickUp(serverYacht);
|
||||
|
||||
if (collidedYacht != null) {
|
||||
GeoPoint originalLocation = serverYacht.getLocation();
|
||||
@@ -404,7 +423,9 @@ public class GameState implements Runnable {
|
||||
collidedYacht.setCurrentVelocity(
|
||||
collidedYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
|
||||
);
|
||||
notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht));
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION)
|
||||
);
|
||||
}
|
||||
|
||||
//Mark Collision
|
||||
@@ -416,7 +437,9 @@ public class GameState implements Runnable {
|
||||
serverYacht.setCurrentVelocity(
|
||||
serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
|
||||
);
|
||||
notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht));
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION)
|
||||
);
|
||||
}
|
||||
|
||||
//Boundary Collision
|
||||
@@ -429,23 +452,22 @@ public class GameState implements Runnable {
|
||||
serverYacht.setCurrentVelocity(
|
||||
serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
|
||||
);
|
||||
notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht));
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION)
|
||||
);
|
||||
}
|
||||
|
||||
//Token Collision
|
||||
Token collidedToken = checkTokenPickUp(serverYacht);
|
||||
if (collidedToken != null) {
|
||||
if (collidedToken.getTokenType() == TokenType.RANDOM) {
|
||||
collidedToken.realiseRandom();
|
||||
}
|
||||
sendServerMessage(serverYacht.getSourceId(),
|
||||
serverYacht.getBoatName() + " has picked up a " + collidedToken.getTokenType()
|
||||
.getName() + " token");
|
||||
sendServerMessage(serverYacht.getSourceId(), serverYacht.getBoatName() + " has picked speed-up token");
|
||||
tokensInPlay.remove(collidedToken);
|
||||
serverYacht.powerUp(collidedToken.getTokenType());
|
||||
logger.debug("Yacht: " + serverYacht.getShortName() + " got powerup " + collidedToken
|
||||
.getTokenType());
|
||||
notifyMessageListeners(MessageFactory.getRaceXML());
|
||||
notifyMessageListeners(MessageFactory.makePickupMessage(serverYacht, collidedToken));
|
||||
notifyMessageListeners(
|
||||
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.TOKEN));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -453,10 +475,11 @@ public class GameState implements Runnable {
|
||||
private void updateVelocity(ServerYacht yacht) {
|
||||
Double trueWindAngle = Math.abs(windDirection - yacht.getHeading());
|
||||
Double boatSpeedInKnots = PolarTable.getBoatSpeed(getWindSpeedKnots(), trueWindAngle);
|
||||
Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier;
|
||||
Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier * yacht.getMaxSpeedMultiplier();
|
||||
if (yacht.getPowerUp() != null) {
|
||||
if (yacht.getPowerUp().equals(TokenType.BOOST)) {
|
||||
maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER;
|
||||
// TODO: 11/09/17 wmu16 CHANGE THIS TO MAGIC NUMBER
|
||||
maxBoatSpeed *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,17 +487,17 @@ public class GameState implements Runnable {
|
||||
// TODO: 15/08/17 remove magic numbers from these equations.
|
||||
if (yacht.getSailIn()) {
|
||||
if (currentVelocity < maxBoatSpeed - 500) {
|
||||
yacht.changeVelocity(maxBoatSpeed / 100);
|
||||
yacht.changeVelocity((maxBoatSpeed / 100) * yacht.getAccelerationMultiplier());
|
||||
} else if (currentVelocity > maxBoatSpeed + 500) {
|
||||
yacht.changeVelocity(-currentVelocity / 200);
|
||||
yacht.changeVelocity((-currentVelocity / 200) * yacht.getAccelerationMultiplier());
|
||||
} else {
|
||||
yacht.setCurrentVelocity(maxBoatSpeed);
|
||||
yacht.setCurrentVelocity((maxBoatSpeed) * yacht.getAccelerationMultiplier());
|
||||
}
|
||||
} else {
|
||||
if (currentVelocity > 3000) {
|
||||
yacht.changeVelocity(-currentVelocity / 200);
|
||||
yacht.changeVelocity((-currentVelocity / 200) * yacht.getAccelerationMultiplier());
|
||||
} else if (currentVelocity > 100) {
|
||||
yacht.changeVelocity(-currentVelocity / 50);
|
||||
yacht.changeVelocity((-currentVelocity / 50) * yacht.getAccelerationMultiplier());
|
||||
} else if (currentVelocity <= 100) {
|
||||
yacht.setCurrentVelocity(0d);
|
||||
}
|
||||
@@ -705,6 +728,9 @@ public class GameState implements Runnable {
|
||||
int blue = customizeData[2] & 0xFF;
|
||||
Color yachtColor = Color.rgb(red, green, blue);
|
||||
playerYacht.setBoatColor(yachtColor);
|
||||
} else if (requestType.equals(CustomizeRequestType.SHAPE)) {
|
||||
String type = new String(customizeData);
|
||||
playerYacht.setBoatType(BoatMeshType.valueOf(type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,14 +11,11 @@ import seng302.gameServer.messages.RaceStatusMessage;
|
||||
import seng302.gameServer.messages.RaceType;
|
||||
import seng302.gameServer.messages.XMLMessage;
|
||||
import seng302.gameServer.messages.XMLMessageSubType;
|
||||
import seng302.gameServer.messages.YachtEventCodeMessage;
|
||||
import seng302.gameServer.messages.YachtEventType;
|
||||
import seng302.model.Player;
|
||||
import seng302.model.ServerYacht;
|
||||
import seng302.model.stream.xml.generator.RaceXMLTemplate;
|
||||
import seng302.model.stream.xml.generator.RegattaXMLTemplate;
|
||||
import seng302.model.token.Token;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
|
||||
/**
|
||||
@@ -131,30 +128,4 @@ public class MessageFactory {
|
||||
XMLMessageSubType.BOAT,
|
||||
xmlGenerator.getBoatsAsXml().length());
|
||||
}
|
||||
|
||||
public static YachtEventCodeMessage makeCollisionMessage(ServerYacht serverYacht) {
|
||||
return new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION);
|
||||
}
|
||||
|
||||
public static YachtEventCodeMessage makePickupMessage(ServerYacht serverYacht, Token token) {
|
||||
YachtEventType yachtEventType = null;
|
||||
switch (token.getTokenType()) {
|
||||
case BOOST:
|
||||
yachtEventType = YachtEventType.TOKEN_VELOCITY;
|
||||
break;
|
||||
case HANDLING:
|
||||
yachtEventType = YachtEventType.TOKEN_HANDLING;
|
||||
break;
|
||||
case WIND_WALKER:
|
||||
yachtEventType = YachtEventType.TOKEN_WIND_WALKER;
|
||||
break;
|
||||
case BUMPER:
|
||||
yachtEventType = YachtEventType.TOKEN_BUMPER;
|
||||
break;
|
||||
case RANDOM:
|
||||
yachtEventType = YachtEventType.TOKEN_RANDOM;
|
||||
break;
|
||||
}
|
||||
return new YachtEventCodeMessage(serverYacht.getSourceId(), yachtEventType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package seng302.gameServer;
|
||||
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
import seng302.discoveryServer.DiscoveryServerClient;
|
||||
|
||||
import javax.jmdns.JmDNS;
|
||||
import javax.jmdns.ServiceInfo;
|
||||
import java.io.IOException;
|
||||
@@ -35,15 +32,12 @@ public class ServerAdvertiser {
|
||||
private static ServerAdvertiser instance = null;
|
||||
private static JmDNS jmdnsInstance = null;
|
||||
private ServiceInfo serviceInfo; // Note: Whenever this is changed, our service will be re-registered on the network.
|
||||
private DiscoveryServerClient repositoryClient;
|
||||
|
||||
private Hashtable<String ,String> props;
|
||||
|
||||
private ServerAdvertiser() throws IOException{
|
||||
jmdnsInstance = JmDNS.create(InetAddress.getByName(getLocalHostIp()));
|
||||
|
||||
repositoryClient = new DiscoveryServerClient();
|
||||
|
||||
props = new Hashtable<>();
|
||||
props.put("map", "");
|
||||
props.put("spacesLeft", "0");
|
||||
@@ -132,9 +126,6 @@ public class ServerAdvertiser {
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
|
||||
ServerListing serverListing = new ServerListing(serverName, props.get("map"), getLocalHostIp(), portNo, Integer.parseInt(props.get("capacity")));
|
||||
repositoryClient.register(serverListing);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,10 +7,6 @@ public class ServerDescription {
|
||||
private String serverName;
|
||||
private String mapName;
|
||||
private Integer numPlayers;
|
||||
private Long lastUpdated;
|
||||
private Long lastRefreshed;
|
||||
|
||||
private static Long EXPIRY_INTERVAL = 5000L;
|
||||
|
||||
public ServerDescription(String serverName, String mapName, Integer numPlayers, Integer capacity, String address, Integer portNum){
|
||||
this.serverName = serverName;
|
||||
@@ -19,7 +15,6 @@ public class ServerDescription {
|
||||
this.address = address;
|
||||
this.portNum = portNum;
|
||||
this.capacity = capacity;
|
||||
lastUpdated = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
@@ -85,20 +80,4 @@ public class ServerDescription {
|
||||
return this.getName().hashCode() + this.getAddress().hashCode() +
|
||||
this.portNumber().hashCode() + this.getMapName().hashCode();
|
||||
}
|
||||
|
||||
public Boolean hasExpired(){
|
||||
return System.currentTimeMillis() - lastUpdated > EXPIRY_INTERVAL;
|
||||
}
|
||||
|
||||
public Boolean serverShouldBeRemoved() {
|
||||
if (lastRefreshed == null) return false;
|
||||
|
||||
System.out.println("SBR" + (System.currentTimeMillis() - lastRefreshed > EXPIRY_INTERVAL));
|
||||
return System.currentTimeMillis() - lastRefreshed > EXPIRY_INTERVAL;
|
||||
}
|
||||
|
||||
public void hasBeenRefreshed(){
|
||||
System.out.println("Was refreshed");
|
||||
lastRefreshed = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import seng302.model.stream.packets.PacketType;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.model.stream.xml.generator.RaceXMLTemplate;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* A class describing a single connection to a Client for the purposes of sending and receiving on
|
||||
@@ -125,7 +126,7 @@ public class ServerToClientThread implements Runnable {
|
||||
lName = all.get(ThreadLocalRandom.current().nextInt(0, all.size()));
|
||||
|
||||
ServerYacht yacht = new ServerYacht(
|
||||
"Yacht", sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ"
|
||||
BoatMeshType.DINGHY, sourceId, sourceId.toString(), fName, fName + " " + lName, "NZ"
|
||||
);
|
||||
|
||||
player = new Player(socket, yacht);
|
||||
|
||||
@@ -14,7 +14,9 @@ public enum BoatAction {
|
||||
TACK_GYBE(4),
|
||||
UPWIND(5),
|
||||
DOWNWIND(6),
|
||||
MAINTAIN_HEADING(7);
|
||||
MAINTAIN_HEADING(7),
|
||||
CONTINUOUSLY_TURNING(8),
|
||||
DEFAULT_TURNING(9);
|
||||
|
||||
private final int type;
|
||||
private static final Map<Integer, BoatAction> intToTypeMap = new HashMap<>();
|
||||
|
||||
@@ -21,10 +21,7 @@ public enum MessageType {
|
||||
REGISTRATION_REQUEST(101),
|
||||
REGISTRATION_RESPONSE(102),
|
||||
CUSTOMIZATION_REQUEST(103),
|
||||
CUSTOMIZATION_RESPONSE(104),
|
||||
REPO_REGISTRATION_REQUEST(201),
|
||||
ROOM_CODE_REQUEST(202),
|
||||
LOBBY_REQUEST(203);
|
||||
CUSTOMIZATION_RESPONSE(104);
|
||||
|
||||
|
||||
private int code;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package seng302.gameServer.messages;
|
||||
|
||||
public class RoomCodeRequest extends Message{
|
||||
private int size = 0;
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public RoomCodeRequest(String roomCode){
|
||||
size = roomCode.length() + 6;
|
||||
|
||||
setHeader(new Header(MessageType.ROOM_CODE_REQUEST, 0x01, (short)getSize()));
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
putInt(roomCode.length(), 6);
|
||||
putBytes(roomCode.getBytes());
|
||||
|
||||
writeCRC();
|
||||
rewind();
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package seng302.gameServer.messages;
|
||||
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
|
||||
public class ServerRegistrationMessage extends Message {
|
||||
private int size;
|
||||
|
||||
public ServerRegistrationMessage(ServerListing serverListing) {
|
||||
String serverName = serverListing.getServerName();
|
||||
String mapName = serverListing.getMapName();
|
||||
String address = serverListing.getAddress();
|
||||
int port = serverListing.getPortNumber();
|
||||
int players = serverListing.getPortNumber();
|
||||
int capacity = serverListing.getCapacity();
|
||||
String roomCode = serverListing.getRoomCode();
|
||||
|
||||
createMessage(serverName, mapName, address, port, players, capacity, roomCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public ServerRegistrationMessage(String serverName, String mapName, String address, int port, int players, int capacity, String roomCode){
|
||||
createMessage(serverName, mapName, address, port, players, capacity, roomCode);
|
||||
}
|
||||
|
||||
private void createMessage(String serverName, String mapName, String address, int port, int players, int capacity, String roomCode){
|
||||
size = serverName.getBytes().length + mapName.length() + address.length() + roomCode.length() + 36;
|
||||
|
||||
setHeader(new Header(MessageType.REPO_REGISTRATION_REQUEST, 0x01, (short) getSize()));
|
||||
allocateBuffer();
|
||||
writeHeaderToBuffer();
|
||||
|
||||
int nameLength = serverName.length();
|
||||
int mapNameLength = mapName.length();
|
||||
int addressLength = address.length();
|
||||
int roomCodeLength = roomCode.length();
|
||||
|
||||
// Put fields here
|
||||
putInt(nameLength, 6);
|
||||
putInt(mapNameLength, 6);
|
||||
putInt(addressLength, 6);
|
||||
putInt(roomCodeLength, 6);
|
||||
|
||||
putInt(port, 4);
|
||||
putInt(players, 4);
|
||||
putInt(capacity, 4);
|
||||
|
||||
putBytes(serverName.getBytes());
|
||||
putBytes(mapName.getBytes());
|
||||
putBytes(address.getBytes());
|
||||
putBytes(roomCode.getBytes());
|
||||
|
||||
writeCRC();
|
||||
rewind();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,11 +5,7 @@ package seng302.gameServer.messages;
|
||||
*/
|
||||
public enum YachtEventType {
|
||||
COLLISION(33),
|
||||
TOKEN_VELOCITY(34),
|
||||
TOKEN_BUMPER(35),
|
||||
TOKEN_HANDLING(36),
|
||||
TOKEN_WIND_WALKER(37),
|
||||
TOKEN_RANDOM(38);
|
||||
TOKEN(34);
|
||||
|
||||
private int code;
|
||||
|
||||
|
||||
@@ -12,14 +12,10 @@ import javafx.beans.property.ReadOnlyIntegerProperty;
|
||||
import javafx.beans.property.ReadOnlyIntegerWrapper;
|
||||
import javafx.beans.property.ReadOnlyLongProperty;
|
||||
import javafx.beans.property.ReadOnlyLongWrapper;
|
||||
import javafx.beans.value.ObservableObjectValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.paint.Color;
|
||||
import jdk.nashorn.internal.objects.annotations.Function;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
|
||||
@@ -39,25 +35,19 @@ public class ClientYacht extends Observable {
|
||||
void notifyRounding(ClientYacht yacht, int legNumber);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PowerUpListener {
|
||||
void notifyPowerUp(ClientYacht yacht, TokenType tokenType);
|
||||
}
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ClientYacht.class);
|
||||
|
||||
|
||||
private String boatType;
|
||||
private BoatMeshType boatType;
|
||||
private Integer sourceId;
|
||||
private String hullID; //matches HullNum in the XML spec.
|
||||
private String shortName;
|
||||
private String boatName;
|
||||
private String country;
|
||||
private Integer position;
|
||||
private TokenType powerUp;
|
||||
|
||||
private Long estimateTimeAtFinish;
|
||||
private Boolean sailIn = false;
|
||||
private Boolean sailIn = true;
|
||||
private Integer currentMarkSeqID = 0;
|
||||
private Long markRoundTime;
|
||||
private Long timeTillNext;
|
||||
@@ -67,18 +57,15 @@ public class ClientYacht extends Observable {
|
||||
private Integer boatStatus;
|
||||
private Double currentVelocity;
|
||||
|
||||
private BoatObject boatObject;
|
||||
|
||||
private List<YachtLocationListener> locationListeners = new ArrayList<>();
|
||||
private List<MarkRoundingListener> markRoundingListeners = new ArrayList<>();
|
||||
private List<PowerUpListener> powerUpListeners = new ArrayList<>();
|
||||
private ReadOnlyDoubleWrapper velocityProperty = new ReadOnlyDoubleWrapper();
|
||||
private ReadOnlyLongWrapper timeTillNextProperty = new ReadOnlyLongWrapper();
|
||||
private ReadOnlyLongWrapper timeSinceLastMarkProperty = new ReadOnlyLongWrapper();
|
||||
private ReadOnlyIntegerWrapper placingProperty = new ReadOnlyIntegerWrapper();
|
||||
private Color colour;
|
||||
|
||||
public ClientYacht(String boatType, Integer sourceId, String hullID, String shortName,
|
||||
public ClientYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName,
|
||||
String boatName, String country) {
|
||||
this.boatType = boatType;
|
||||
this.sourceId = sourceId;
|
||||
@@ -102,7 +89,7 @@ public class ClientYacht extends Observable {
|
||||
super.addObserver(o);
|
||||
}
|
||||
|
||||
public String getBoatType() {
|
||||
public BoatMeshType getBoatType() {
|
||||
return boatType;
|
||||
}
|
||||
|
||||
@@ -213,17 +200,6 @@ public class ClientYacht extends Observable {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void setPowerUp(TokenType tokenType) {
|
||||
this.powerUp = tokenType;
|
||||
for (PowerUpListener listener : powerUpListeners) {
|
||||
listener.notifyPowerUp(this, tokenType);
|
||||
}
|
||||
}
|
||||
|
||||
public TokenType getPowerUp() {
|
||||
return powerUp;
|
||||
}
|
||||
|
||||
public void toggleSail() {
|
||||
sailIn = !sailIn;
|
||||
}
|
||||
@@ -293,10 +269,6 @@ public class ClientYacht extends Observable {
|
||||
markRoundingListeners.add(listener);
|
||||
}
|
||||
|
||||
public void addPowerUpListener(PowerUpListener listener) {
|
||||
powerUpListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeMarkRoundingListener(MarkRoundingListener listener) {
|
||||
markRoundingListeners.remove(listener);
|
||||
}
|
||||
@@ -317,12 +289,4 @@ public class ClientYacht extends Observable {
|
||||
public Double getCurrentVelocity() {
|
||||
return currentVelocity;
|
||||
}
|
||||
|
||||
public void setBoatObject(BoatObject newBoatObject) {
|
||||
this.boatObject = newBoatObject;
|
||||
}
|
||||
|
||||
public BoatObject getBoatObject() {
|
||||
return this.boatObject;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package seng302.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javafx.scene.input.KeyCode;
|
||||
|
||||
public class GameKeyBind {
|
||||
|
||||
private static GameKeyBind instance;
|
||||
private Map<KeyCode, KeyAction> keyToActionMap;
|
||||
private Map<KeyAction, KeyCode> actionToKeyMap;
|
||||
private Boolean continuouslyTurning;
|
||||
|
||||
|
||||
private GameKeyBind() {
|
||||
setToDefault();
|
||||
}
|
||||
|
||||
public void setToDefault() {
|
||||
actionToKeyMap = new HashMap<>();
|
||||
keyToActionMap = new HashMap<>();
|
||||
continuouslyTurning = false;
|
||||
// default key bindings
|
||||
ArrayList<KeyCode> keys = new ArrayList<>();
|
||||
keys.add(KeyCode.Z);
|
||||
keys.add(KeyCode.X);
|
||||
keys.add(KeyCode.SPACE);
|
||||
keys.add(KeyCode.SHIFT);
|
||||
keys.add(KeyCode.ENTER);
|
||||
keys.add(KeyCode.PAGE_UP);
|
||||
keys.add(KeyCode.PAGE_DOWN);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
actionToKeyMap.put(KeyAction.getType(i + 1), keys.get(i));
|
||||
keyToActionMap.put(keys.get(i), KeyAction.getType(i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
public static GameKeyBind getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new GameKeyBind();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public KeyCode getKeyCode(KeyAction keyAction) {
|
||||
return instance.actionToKeyMap.get(keyAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds a key to a key action
|
||||
*
|
||||
* @return true if successfully bind
|
||||
*/
|
||||
public boolean bindKeyToAction(KeyCode keyCode, KeyAction keyAction) {
|
||||
if (instance.keyToActionMap.containsKey(keyCode)) {
|
||||
// if the key has been bound to other action, return false
|
||||
return false;
|
||||
} else {
|
||||
instance.keyToActionMap.put(keyCode, keyAction); // add key -> action
|
||||
KeyCode oldKeyCode = instance.actionToKeyMap
|
||||
.get(keyAction); // get old key for the action
|
||||
instance.keyToActionMap.remove(oldKeyCode); // remove the old key -> action
|
||||
instance.actionToKeyMap
|
||||
.replace(keyAction, keyCode); // replace the old key by the newer one
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleTurningMode() {
|
||||
continuouslyTurning = !continuouslyTurning;
|
||||
}
|
||||
|
||||
public Boolean isContinuouslyTurning() {
|
||||
return continuouslyTurning;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package seng302.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum KeyAction {
|
||||
ZOOM_IN(1),
|
||||
ZOOM_OUT(2),
|
||||
VMG(3),
|
||||
SAILS_STATE(4),
|
||||
TACK_GYBE(5),
|
||||
UPWIND(6),
|
||||
DOWNWIND(7);
|
||||
|
||||
private final int type;
|
||||
private static final Map<Integer, KeyAction> intToTypeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (KeyAction type : KeyAction.values()) {
|
||||
intToTypeMap.put(type.getValue(), type);
|
||||
}
|
||||
}
|
||||
|
||||
KeyAction(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static KeyAction getType(int value) {
|
||||
return intToTypeMap.get(value);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package seng302.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -8,10 +9,7 @@ import seng302.gameServer.messages.BoatStatus;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.GeoUtility;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
|
||||
@@ -20,12 +18,14 @@ import java.util.Observer;
|
||||
*/
|
||||
public class ServerYacht {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ClientYacht.class);
|
||||
|
||||
public static final Double TURN_STEP = 5.0;
|
||||
private Logger logger = LoggerFactory.getLogger(ServerYacht.class);
|
||||
|
||||
//Boat info
|
||||
private String boatType;
|
||||
private BoatMeshType boatType;
|
||||
private Double turnStep = 5.0;
|
||||
private Double maxSpeedMultiplier = 1.0;
|
||||
private Double turnStepMultiplier = 1.0;
|
||||
private Double accelerationMultiplier = 1.0;
|
||||
private Integer sourceId;
|
||||
private String hullID; //matches HullNum in the XML spec.
|
||||
private String shortName;
|
||||
@@ -56,10 +56,12 @@ public class ServerYacht {
|
||||
private TokenType powerUp;
|
||||
private Long powerUpStartTime;
|
||||
|
||||
//turning mode
|
||||
private Boolean continuouslyTurning;
|
||||
|
||||
public ServerYacht(String boatType, Integer sourceId, String hullID, String shortName,
|
||||
public ServerYacht(BoatMeshType boatType, Integer sourceId, String hullID, String shortName,
|
||||
String boatName, String country) {
|
||||
this.boatType = boatType;
|
||||
setBoatType(boatType);
|
||||
this.boatStatus = BoatStatus.PRESTART;
|
||||
this.sourceId = sourceId;
|
||||
this.hullID = hullID;
|
||||
@@ -80,6 +82,8 @@ public class ServerYacht {
|
||||
this.hasEnteredRoundingZone = false;
|
||||
this.hasPassedLine = false;
|
||||
this.hasPassedThroughGate = false;
|
||||
|
||||
this.continuouslyTurning = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +133,7 @@ public class ServerYacht {
|
||||
* @param amount the amount by which to adjust the boat heading.
|
||||
*/
|
||||
public void adjustHeading(Double amount) {
|
||||
Double newVal = heading + amount;
|
||||
Double newVal = heading + (amount * turnStepMultiplier);
|
||||
lastHeading = heading;
|
||||
heading = (double) Math.floorMod(newVal.longValue(), 360L);
|
||||
}
|
||||
@@ -174,7 +178,7 @@ public class ServerYacht {
|
||||
if (isAuto) {
|
||||
turnTowardsHeading(autoHeading);
|
||||
if (Math.abs(heading - autoHeading)
|
||||
<= TURN_STEP) { //Cancel when within 1 turn step of target.
|
||||
<= turnStep) { //Cancel when within 1 turn step of target.
|
||||
isAuto = false;
|
||||
}
|
||||
}
|
||||
@@ -187,44 +191,52 @@ public class ServerYacht {
|
||||
public void turnUpwind() {
|
||||
disableAutoPilot();
|
||||
Double normalizedHeading = normalizeHeading();
|
||||
if (continuouslyTurning) {
|
||||
adjustHeading(turnStep);
|
||||
} else {
|
||||
if (normalizedHeading == 0) {
|
||||
if (lastHeading < 180) {
|
||||
adjustHeading(-TURN_STEP);
|
||||
adjustHeading(-turnStep);
|
||||
} else {
|
||||
adjustHeading(TURN_STEP);
|
||||
adjustHeading(turnStep);
|
||||
}
|
||||
} else if (normalizedHeading == 180) {
|
||||
if (lastHeading < 180) {
|
||||
adjustHeading(TURN_STEP);
|
||||
adjustHeading(turnStep);
|
||||
} else {
|
||||
adjustHeading(-TURN_STEP);
|
||||
adjustHeading(-turnStep);
|
||||
}
|
||||
} else if (normalizedHeading < 180) {
|
||||
adjustHeading(-TURN_STEP);
|
||||
adjustHeading(-turnStep);
|
||||
} else {
|
||||
adjustHeading(TURN_STEP);
|
||||
adjustHeading(turnStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void turnDownwind() {
|
||||
disableAutoPilot();
|
||||
Double normalizedHeading = normalizeHeading();
|
||||
if (continuouslyTurning) {
|
||||
adjustHeading(-turnStep);
|
||||
} else {
|
||||
if (normalizedHeading == 0) {
|
||||
if (lastHeading < 180) {
|
||||
adjustHeading(TURN_STEP);
|
||||
adjustHeading(turnStep);
|
||||
} else {
|
||||
adjustHeading(-TURN_STEP);
|
||||
adjustHeading(-turnStep);
|
||||
}
|
||||
} else if (normalizedHeading == 180) {
|
||||
if (lastHeading < 180) {
|
||||
adjustHeading(-TURN_STEP);
|
||||
adjustHeading(-turnStep);
|
||||
} else {
|
||||
adjustHeading(TURN_STEP);
|
||||
adjustHeading(turnStep);
|
||||
}
|
||||
} else if (normalizedHeading < 180) {
|
||||
adjustHeading(TURN_STEP);
|
||||
adjustHeading(turnStep);
|
||||
} else {
|
||||
adjustHeading(-TURN_STEP);
|
||||
adjustHeading(-turnStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +280,9 @@ public class ServerYacht {
|
||||
private void turnTowardsHeading(Double newHeading) {
|
||||
Double newVal = heading - newHeading;
|
||||
if (Math.floorMod(newVal.longValue(), 360L) > 180) {
|
||||
adjustHeading(TURN_STEP / 5);
|
||||
adjustHeading(turnStep / 5);
|
||||
} else {
|
||||
adjustHeading(-TURN_STEP / 5);
|
||||
adjustHeading(-turnStep / 5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,4 +433,27 @@ public class ServerYacht {
|
||||
return boatColor;
|
||||
}
|
||||
|
||||
public void setBoatType(BoatMeshType boatType) {
|
||||
this.accelerationMultiplier = boatType.accelerationMultiplier;
|
||||
this.maxSpeedMultiplier = boatType.maxSpeedMultiplier;
|
||||
this.turnStepMultiplier = boatType.turnStep;
|
||||
this.boatType = boatType;
|
||||
}
|
||||
|
||||
public Double getMaxSpeedMultiplier() {
|
||||
return maxSpeedMultiplier;
|
||||
}
|
||||
|
||||
public Double getAccelerationMultiplier(){
|
||||
return accelerationMultiplier;
|
||||
}
|
||||
|
||||
|
||||
public BoatMeshType getBoatType() {
|
||||
return boatType;
|
||||
}
|
||||
|
||||
public void setContinuouslyTurning(Boolean continuouslyTurning) {
|
||||
this.continuouslyTurning = continuouslyTurning;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ public enum PacketType {
|
||||
RACE_REGISTRATION_REQUEST,
|
||||
RACE_REGISTRATION_RESPONSE,
|
||||
RACE_CUSTOMIZATION_REQUEST,
|
||||
RACE_CUSTOMIZATION_RESPONSE,
|
||||
|
||||
SERVER_REGISTRATION, ROOM_CODE_REQUEST, LOBBY_REQUEST;
|
||||
RACE_CUSTOMIZATION_RESPONSE;
|
||||
|
||||
public static PacketType assignPacketType(int packetType, byte[] payload){
|
||||
switch(packetType){
|
||||
@@ -67,10 +65,6 @@ public enum PacketType {
|
||||
return RACE_CUSTOMIZATION_REQUEST;
|
||||
case 104:
|
||||
return RACE_CUSTOMIZATION_RESPONSE;
|
||||
case 201:
|
||||
return SERVER_REGISTRATION;
|
||||
case 202:
|
||||
return ROOM_CODE_REQUEST;
|
||||
default:
|
||||
}
|
||||
return OTHER;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package seng302.model.token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import seng302.model.GeoPoint;
|
||||
|
||||
/**
|
||||
@@ -13,7 +9,6 @@ import seng302.model.GeoPoint;
|
||||
public class Token extends GeoPoint {
|
||||
|
||||
private TokenType tokenType;
|
||||
private Random random = new Random();
|
||||
|
||||
public Token(TokenType tokenType, double lat, double lng) {
|
||||
super(lat, lng);
|
||||
@@ -23,22 +18,4 @@ public class Token extends GeoPoint {
|
||||
public TokenType getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a random type to the token (including the random type token)
|
||||
*/
|
||||
public void assignRandomType() {
|
||||
tokenType = TokenType.values()[random.nextInt(TokenType.values().length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a random, concrete type to the token (cannot be the random type)
|
||||
*/
|
||||
public void realiseRandom() {
|
||||
List<TokenType> tokenTypeList = new ArrayList<>(Arrays.asList(TokenType.values()));
|
||||
tokenTypeList.remove(TokenType.RANDOM);
|
||||
tokenType = tokenTypeList.get(random.nextInt(tokenTypeList.size()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,32 +5,27 @@ package seng302.model.token;
|
||||
* Created by wmu16 on 28/08/17.
|
||||
*/
|
||||
public enum TokenType {
|
||||
|
||||
BOOST(0, "Boost", 10_000),
|
||||
HANDLING(1, "Handling", 10_000),
|
||||
BUMPER(2, "Bumper", 10_000),
|
||||
WIND_WALKER(3, "Wind Walker", 10_000),
|
||||
RANDOM(4, "Random", 10_000);
|
||||
BOOST(0),
|
||||
HANDLING(1);
|
||||
|
||||
private int value;
|
||||
private String name;
|
||||
private int timeout;
|
||||
|
||||
TokenType(int value, String name, int timeout) {
|
||||
TokenType(int value) {
|
||||
this.value = value;
|
||||
this.name = name;
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
public static TokenType getToken(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return BOOST;
|
||||
case 1:
|
||||
return HANDLING;
|
||||
default:
|
||||
return BOOST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,10 @@ public class Sounds {
|
||||
private static MediaPlayer soundEffect;
|
||||
private static MediaPlayer soundPlayer;
|
||||
private static MediaPlayer hoverSoundPlayer;
|
||||
private static MediaPlayer crashSoundPlayer;
|
||||
|
||||
private static boolean hoverInitialized = false;
|
||||
private static boolean crashInitialized = false;
|
||||
private static boolean musicMuted = false;
|
||||
private static boolean soundEffectsMuted = false;
|
||||
|
||||
@@ -155,11 +157,17 @@ public class Sounds {
|
||||
|
||||
public static void playCrashSound() {
|
||||
if (!soundEffectsMuted) {
|
||||
Media crashSound = new Media(
|
||||
if (!crashInitialized) {
|
||||
Media pickupSound = new Media(
|
||||
Sounds.class.getClassLoader().getResource("sounds/Large-metal-door-slam.mp3")
|
||||
.toString());
|
||||
soundPlayer = new MediaPlayer(crashSound);
|
||||
soundPlayer.play();
|
||||
crashSoundPlayer = new MediaPlayer(pickupSound);
|
||||
crashInitialized = true;
|
||||
}
|
||||
if (crashSoundPlayer != null) {
|
||||
crashSoundPlayer.stop();
|
||||
}
|
||||
crashSoundPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,10 +184,10 @@ public class Sounds {
|
||||
public static void playHoverSound() {
|
||||
if (!soundEffectsMuted) {
|
||||
if (!hoverInitialized) {
|
||||
Media crashSound = new Media(
|
||||
Media hoverSound = new Media(
|
||||
Sounds.class.getClassLoader().getResource("sounds/Error-sound-effect.mp3")
|
||||
.toString());
|
||||
hoverSoundPlayer = new MediaPlayer(crashSound);
|
||||
hoverSoundPlayer = new MediaPlayer(hoverSound);
|
||||
hoverInitialized = true;
|
||||
}
|
||||
hoverSoundPlayer.setVolume(0.5);
|
||||
|
||||
@@ -18,6 +18,7 @@ import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.model.token.Token;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* Utilities for parsing XML documents
|
||||
@@ -139,18 +140,16 @@ public class XMLParser {
|
||||
if (currentBoat.getNodeName().equals("Boat")) {
|
||||
// Boat boat = new Boat(currentBoat);
|
||||
ClientYacht yacht = new ClientYacht(
|
||||
XMLParser.getNodeAttributeString(currentBoat, "Type"),
|
||||
BoatMeshType.valueOf(XMLParser.getNodeAttributeString(currentBoat, "Type")),
|
||||
XMLParser.getNodeAttributeInt(currentBoat, "SourceID"),
|
||||
XMLParser.getNodeAttributeString(currentBoat, "HullNum"),
|
||||
XMLParser.getNodeAttributeString(currentBoat, "ShortName"),
|
||||
XMLParser.getNodeAttributeString(currentBoat, "BoatName"),
|
||||
XMLParser.getNodeAttributeString(currentBoat, "Country"));
|
||||
yacht.setColour(Color.web(getNodeAttributeString(currentBoat, "Color")));
|
||||
if (yacht.getBoatType().equals("Yacht")) {
|
||||
competingBoats.put(yacht.getSourceId(), yacht);
|
||||
}
|
||||
}
|
||||
}
|
||||
return competingBoats;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ import seng302.gameServer.messages.BoatAction;
|
||||
import seng302.gameServer.messages.BoatStatus;
|
||||
import seng302.gameServer.messages.YachtEventType;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.model.GameKeyBind;
|
||||
import seng302.model.KeyAction;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.stream.packets.StreamPacket;
|
||||
import seng302.model.stream.parser.MarkRoundingData;
|
||||
@@ -37,7 +39,6 @@ import seng302.model.stream.parser.RaceStatusData;
|
||||
import seng302.model.stream.parser.YachtEventData;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.stream.xml.parser.RegattaXMLData;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.utilities.StreamParser;
|
||||
import seng302.utilities.XMLGenerator;
|
||||
@@ -67,6 +68,8 @@ public class GameClient {
|
||||
|
||||
private ArrayList<ClientYacht> finishedBoats = new ArrayList<>();
|
||||
|
||||
private GameKeyBind gameKeyBind; // all the key binding setting.
|
||||
|
||||
private ObservableList<String> clientLobbyList = FXCollections.observableArrayList();
|
||||
|
||||
/**
|
||||
@@ -76,6 +79,7 @@ public class GameClient {
|
||||
*/
|
||||
public GameClient(Pane holder) {
|
||||
this.holderPane = holder;
|
||||
this.gameKeyBind = GameKeyBind.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,7 +250,12 @@ public class GameClient {
|
||||
break;
|
||||
|
||||
case YACHT_EVENT_CODE:
|
||||
processYachtEvent(StreamParser.extractYachtEventCode(packet));
|
||||
YachtEventData yachtEventData = StreamParser.extractYachtEventCode(packet);
|
||||
if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) {
|
||||
showCollisionAlert(StreamParser.extractYachtEventCode(packet));
|
||||
} else if (yachtEventData.getEventId() == YachtEventType.TOKEN.getCode()) {
|
||||
showPickUp();
|
||||
}
|
||||
break;
|
||||
|
||||
case CHATTER_TEXT:
|
||||
@@ -369,16 +378,16 @@ public class GameClient {
|
||||
}
|
||||
return;
|
||||
}
|
||||
switch (e.getCode()) {
|
||||
case SPACE: // align with vmg
|
||||
socketThread.sendBoatAction(BoatAction.VMG); break;
|
||||
case PAGE_UP: // upwind
|
||||
socketThread.sendBoatAction(BoatAction.UPWIND); break;
|
||||
case PAGE_DOWN: // downwind
|
||||
socketThread.sendBoatAction(BoatAction.DOWNWIND); break;
|
||||
case ENTER: // tack/gybe
|
||||
|
||||
if (gameKeyBind.getKeyCode(KeyAction.VMG) == e.getCode()) { // align with vmg
|
||||
socketThread.sendBoatAction(BoatAction.VMG);
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()) { // upwind
|
||||
socketThread.sendBoatAction(BoatAction.UPWIND);
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) { // downwind
|
||||
socketThread.sendBoatAction(BoatAction.DOWNWIND);
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.TACK_GYBE) == e.getCode()) { // tack/gybe
|
||||
// if chat box is active take whatever is in there and send it to server
|
||||
socketThread.sendBoatAction(BoatAction.TACK_GYBE); break;
|
||||
socketThread.sendBoatAction(BoatAction.TACK_GYBE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,15 +396,13 @@ public class GameClient {
|
||||
if (raceView.isChatInputFocused()) {
|
||||
return;
|
||||
}
|
||||
switch (e.getCode()) {
|
||||
//TODO 12/07/17 Determine the sail state and send the appropriate packet (eg. if sails are in, send a sail out packet)
|
||||
case SHIFT: // sails in/sails out
|
||||
|
||||
if (gameKeyBind.getKeyCode(KeyAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
|
||||
socketThread.sendBoatAction(BoatAction.SAILS_IN);
|
||||
allBoatsMap.get(socketThread.getClientId()).toggleSail();
|
||||
break;
|
||||
case PAGE_UP:
|
||||
case PAGE_DOWN:
|
||||
socketThread.sendBoatAction(BoatAction.MAINTAIN_HEADING); break;
|
||||
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()
|
||||
|| gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) {
|
||||
socketThread.sendBoatAction(BoatAction.MAINTAIN_HEADING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,34 +410,6 @@ public class GameClient {
|
||||
return courseData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appropriately displays the event client side given the YachtEventCode (collision / token..)
|
||||
*
|
||||
* @param yachtEventData The YachtEvent data packet
|
||||
*/
|
||||
private void processYachtEvent(YachtEventData yachtEventData) {
|
||||
if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) {
|
||||
showCollisionAlert(yachtEventData);
|
||||
} else {
|
||||
TokenType tokenType = null;
|
||||
if (yachtEventData.getEventId() == YachtEventType.TOKEN_VELOCITY.getCode()) {
|
||||
tokenType = TokenType.BOOST;
|
||||
} else if (yachtEventData.getEventId() == YachtEventType.TOKEN_BUMPER.getCode()) {
|
||||
tokenType = TokenType.BUMPER;
|
||||
} else if (yachtEventData.getEventId() == YachtEventType.TOKEN_HANDLING.getCode()) {
|
||||
tokenType = TokenType.HANDLING;
|
||||
} else if (yachtEventData.getEventId() == YachtEventType.TOKEN_RANDOM.getCode()) {
|
||||
tokenType = TokenType.RANDOM;
|
||||
} else if (yachtEventData.getEventId() == YachtEventType.TOKEN_WIND_WALKER.getCode()) {
|
||||
tokenType = TokenType.WIND_WALKER;
|
||||
}
|
||||
|
||||
showTokenPickUp(tokenType);
|
||||
allBoatsMap.get(yachtEventData.getSubjectId().intValue()).setPowerUp(tokenType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells race view to show a collision animation.
|
||||
*/
|
||||
@@ -444,18 +423,8 @@ public class GameClient {
|
||||
}
|
||||
|
||||
// TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user
|
||||
private void showTokenPickUp(TokenType tokenType) {
|
||||
private void showPickUp() {
|
||||
Sounds.playTokenPickupSound();
|
||||
switch (tokenType) {
|
||||
case BOOST:
|
||||
break;
|
||||
case HANDLING:
|
||||
break;
|
||||
case WIND_WALKER:
|
||||
break;
|
||||
case BUMPER:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void formatAndSendChatMessage(String rawChat) {
|
||||
@@ -490,4 +459,14 @@ public class GameClient {
|
||||
public Map<Integer, ClientYacht> getAllBoatsMap() {
|
||||
return allBoatsMap;
|
||||
}
|
||||
|
||||
public void sendToggleTurningModePacket() {
|
||||
if (socketThread != null) {
|
||||
if (gameKeyBind.isContinuouslyTurning()) {
|
||||
socketThread.sendBoatAction(BoatAction.CONTINUOUSLY_TURNING);
|
||||
} else {
|
||||
socketThread.sendBoatAction(BoatAction.DEFAULT_TURNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,10 @@ import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.token.Token;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.cameras.ChaseCamera;
|
||||
import seng302.visualiser.cameras.IsometricCamera;
|
||||
import seng302.visualiser.cameras.RaceCamera;
|
||||
import seng302.visualiser.cameras.TopDownCamera;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
import seng302.visualiser.fxObjects.MarkArrowFactory;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
import seng302.visualiser.fxObjects.assets_3D.Marker3D;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||
@@ -57,8 +52,6 @@ public class GameView3D {
|
||||
private SubScene view;
|
||||
// ParallelCamera camera;
|
||||
private PerspectiveCamera camera;
|
||||
private PerspectiveCamera camera2;
|
||||
private PerspectiveCamera camera3;
|
||||
private Group gameObjects;
|
||||
|
||||
private double bufferSize = 0;
|
||||
@@ -95,21 +88,13 @@ public class GameView3D {
|
||||
}
|
||||
|
||||
public GameView3D () {
|
||||
camera = new IsometricCamera(DEFAULT_CAMERA_X, DEFAULT_CAMERA_Y, DEFAULT_CAMERA_DEPTH);
|
||||
camera = new PerspectiveCamera(true);
|
||||
camera.getTransforms().addAll(
|
||||
new Translate(DEFAULT_CAMERA_X,DEFAULT_CAMERA_Y, DEFAULT_CAMERA_DEPTH)
|
||||
);
|
||||
camera.setFarClip(600);
|
||||
camera.setNearClip(0.1);
|
||||
camera.setFieldOfView(FOV);
|
||||
|
||||
camera2 = new TopDownCamera();
|
||||
camera2.setFarClip(600);
|
||||
camera2.setNearClip(0.1);
|
||||
camera2.setFieldOfView(FOV);
|
||||
|
||||
camera3 = new ChaseCamera();
|
||||
camera3.setFarClip(600);
|
||||
camera3.setNearClip(0.1);
|
||||
camera3.setFieldOfView(FOV);
|
||||
|
||||
gameObjects = new Group();
|
||||
root3D = new Group(camera, gameObjects);
|
||||
view = new SubScene(
|
||||
@@ -421,46 +406,35 @@ public class GameView3D {
|
||||
public void cameraMovement(KeyEvent event) {
|
||||
switch (event.getCode()) {
|
||||
case NUMPAD8:
|
||||
view.getCamera().getTransforms().addAll(new Rotate(0.5, new Point3D(1, 0, 0)));
|
||||
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(1,0,0)));
|
||||
break;
|
||||
case NUMPAD2:
|
||||
view.getCamera().getTransforms().addAll(new Rotate(-0.5, new Point3D(1, 0, 0)));
|
||||
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(1,0,0)));
|
||||
break;
|
||||
case NUMPAD4:
|
||||
view.getCamera().getTransforms().addAll(new Rotate(-0.5, new Point3D(0, 1, 0)));
|
||||
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(0,1,0)));
|
||||
break;
|
||||
case NUMPAD6:
|
||||
view.getCamera().getTransforms().addAll(new Rotate(0.5, new Point3D(0, 1, 0)));
|
||||
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(0,1,0)));
|
||||
break;
|
||||
case Z:
|
||||
((RaceCamera) view.getCamera()).zoomIn();
|
||||
camera.getTransforms().addAll(new Translate(0, 0, 1.5));
|
||||
break;
|
||||
case X:
|
||||
((RaceCamera) view.getCamera()).zoomOut();
|
||||
camera.getTransforms().addAll(new Translate(0, 0, -1.5));
|
||||
break;
|
||||
case W:
|
||||
view.getCamera().getTransforms().addAll(new Translate(0, -1, 0));
|
||||
camera.getTransforms().addAll(new Translate(0, -1, 0));
|
||||
break;
|
||||
case S:
|
||||
view.getCamera().getTransforms().addAll(new Translate(0, 1, 0));
|
||||
camera.getTransforms().addAll(new Translate(0, 1, 0));
|
||||
break;
|
||||
case A:
|
||||
view.getCamera().getTransforms().addAll(new Translate(-1, 0, 0));
|
||||
camera.getTransforms().addAll(new Translate(-1, 0, 0));
|
||||
break;
|
||||
case D:
|
||||
view.getCamera().getTransforms().addAll(new Translate(1, 0, 0));
|
||||
camera.getTransforms().addAll(new Translate(1, 0, 0));
|
||||
break;
|
||||
case F1:
|
||||
if (view.getCamera().equals(camera)) {
|
||||
view.setCamera(camera2);
|
||||
if (view.getCamera() instanceof TopDownCamera) {
|
||||
((RaceCamera) view.getCamera()).zoomIn();
|
||||
}
|
||||
} else if (view.getCamera().equals(camera2)) {
|
||||
view.setCamera(camera3);
|
||||
} else {
|
||||
view.setCamera(camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,7 +460,7 @@ public class GameView3D {
|
||||
final List<Group> wakes = new ArrayList<>();
|
||||
for (ClientYacht clientYacht : yachts) {
|
||||
Color colour = clientYacht.getColour();
|
||||
newBoat = new BoatObject();
|
||||
newBoat = new BoatObject(clientYacht.getBoatType());
|
||||
newBoat.setFill(colour);
|
||||
boatObjects.put(clientYacht, newBoat);
|
||||
wakesGroup.getChildren().add(newBoat.getWake());
|
||||
@@ -497,11 +471,6 @@ public class GameView3D {
|
||||
Point2D p2d = findScaledXY(lat, lon);
|
||||
bo.moveTo(p2d.getX(), p2d.getY(), heading, velocity, sailIn, windDir);
|
||||
});
|
||||
|
||||
if (clientYacht.getSourceId().equals(
|
||||
ViewManager.getInstance().getGameClient().getServerThread().getClientId())) {
|
||||
((ChaseCamera) camera3).setPlayerBoat(newBoat);
|
||||
}
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
gameObjects.getChildren().addAll(wakes);
|
||||
@@ -588,27 +557,7 @@ public class GameView3D {
|
||||
mapTokens = new ArrayList<>();
|
||||
for (Token token : newTokens) {
|
||||
Point2D location = findScaledXY(token.getLat(), token.getLng());
|
||||
|
||||
ModelType modelType = null;
|
||||
switch (token.getTokenType()) {
|
||||
case BOOST:
|
||||
modelType = ModelType.VELOCITY_PICKUP;
|
||||
break;
|
||||
case HANDLING:
|
||||
modelType = ModelType.HANDLING_PICKUP;
|
||||
break;
|
||||
case BUMPER:
|
||||
modelType = ModelType.BUMPER_PICKUP;
|
||||
break;
|
||||
case RANDOM:
|
||||
modelType = ModelType.RANDOM_PICKUP;
|
||||
break;
|
||||
case WIND_WALKER:
|
||||
modelType = ModelType.WIND_WALKER_PICKUP;
|
||||
break;
|
||||
}
|
||||
|
||||
Node tokenObject = ModelFactory.importModel(modelType).getAssets();
|
||||
Node tokenObject = ModelFactory.importModel(ModelType.VELOCITY_PICKUP).getAssets();
|
||||
tokenObject.setLayoutX(location.getX());
|
||||
tokenObject.setLayoutY(location.getY());
|
||||
mapTokens.add(tokenObject);
|
||||
@@ -620,6 +569,7 @@ public class GameView3D {
|
||||
}
|
||||
|
||||
public void setBoatAsPlayer (ClientYacht playerYacht) {
|
||||
playerYacht.toggleSail();
|
||||
playerBoatAnimationTimer = new AnimationTimer() {
|
||||
|
||||
double count = 60;
|
||||
|
||||
@@ -6,10 +6,11 @@ import seng302.gameServer.ServerDescription;
|
||||
import javax.jmdns.JmDNS;
|
||||
import javax.jmdns.ServiceEvent;
|
||||
import javax.jmdns.ServiceListener;
|
||||
import javax.jmdns.impl.JmDNSImpl;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
|
||||
|
||||
@@ -17,7 +18,6 @@ import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
|
||||
* Listens for servers on the local network
|
||||
*/
|
||||
public class ServerListener{
|
||||
private static Integer SERVICE_REFRESH_INTERVAL = 5 * 1000;
|
||||
private static ServerListener instance;
|
||||
private ServerListenerDelegate delegate;
|
||||
private JmDNS jmdns = null;
|
||||
@@ -91,16 +91,8 @@ public class ServerListener{
|
||||
|
||||
private ServerListener() throws IOException {
|
||||
jmdns = JmDNS.create(InetAddress.getByName(getLocalHostIp()));
|
||||
|
||||
listener = new GameServeMonitor();
|
||||
jmdns.addServiceListener(ServerAdvertiser.SERVICE_TYPE, listener);
|
||||
|
||||
/*new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
}, 50, SERVICE_REFRESH_INTERVAL);*/
|
||||
}
|
||||
|
||||
public static ServerListener getInstance() throws IOException {
|
||||
@@ -118,25 +110,4 @@ public class ServerListener{
|
||||
public void setDelegate(ServerListenerDelegate delegate){
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
public void refresh(){
|
||||
ArrayList<ServerDescription> servers = new ArrayList<>(listener.servers);
|
||||
|
||||
for (ServerDescription serverDescription : servers){
|
||||
if (serverDescription.hasExpired()){
|
||||
jmdns.requestServiceInfo(ServerAdvertiser.SERVICE_TYPE, serverDescription.getName());
|
||||
}
|
||||
else{
|
||||
serverDescription.hasBeenRefreshed();
|
||||
}
|
||||
}
|
||||
|
||||
for (ServerDescription server : servers){
|
||||
if (server.serverShouldBeRemoved()){
|
||||
listener.servers.remove(server);
|
||||
delegate.serverRemoved(new ArrayList<ServerDescription>(listener.servers));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
package seng302.visualiser.cameras;
|
||||
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Point3D;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Transform;
|
||||
import javafx.scene.transform.Translate;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
|
||||
|
||||
public class ChaseCamera extends PerspectiveCamera implements RaceCamera {
|
||||
|
||||
private ObservableList<Transform> transforms;
|
||||
private BoatObject playerBoat;
|
||||
|
||||
public ChaseCamera() {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
}
|
||||
|
||||
public void setPlayerBoat(BoatObject playerBoat) {
|
||||
this.playerBoat = playerBoat;
|
||||
|
||||
this.playerBoat.layoutXProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue,
|
||||
Number newValue) {
|
||||
updateCameraX((Double) oldValue, (Double) newValue);
|
||||
}
|
||||
});
|
||||
this.playerBoat.layoutYProperty().addListener(new ChangeListener<Number>() {
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue,
|
||||
Number newValue) {
|
||||
updateCameraY((Double) oldValue, (Double) newValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void updateCameraX(Double oldXValue, Double newXValue) {
|
||||
if (transforms.size() == 0) { // boat is placed and then moved at start,
|
||||
transforms.addAll(
|
||||
new Translate(playerBoat.getLayoutX() - 30, playerBoat.getLayoutY() - 30, -125),
|
||||
new Rotate(80, new Point3D(0, 0, 1))
|
||||
);
|
||||
} else {
|
||||
transforms.addAll(new Translate(newXValue - oldXValue, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCameraY(Double oldYValue, Double newYValue) {
|
||||
transforms.addAll(new Translate(0, (newYValue - oldYValue), 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoomIn() {
|
||||
transforms.addAll(new Translate(0, 0, 1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoomOut() {
|
||||
transforms.addAll(new Translate(0, 0, -1.5));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
These have been left intentionally empty for now. it would be cool to be able to pan around the boat and have the camera move around the boat though.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void panLeft() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panRight() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panUp() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panDown() {
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package seng302.visualiser.cameras;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.transform.Transform;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
public class IsometricCamera extends PerspectiveCamera implements RaceCamera {
|
||||
|
||||
ObservableList<Transform> transforms;
|
||||
|
||||
public IsometricCamera(Double cameraStartX, Double cameraStartY, Double cameraDepth) {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
transforms.addAll(new Translate(cameraStartX, cameraStartY, cameraDepth));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoomIn() {
|
||||
transforms.addAll(new Translate(0, 0, 1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoomOut() {
|
||||
transforms.addAll(new Translate(0, 0, -1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panLeft() {
|
||||
transforms.addAll(new Translate(-1, 0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panRight() {
|
||||
transforms.addAll(new Translate(1, 0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panUp() {
|
||||
transforms.addAll(new Translate(0, -1, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panDown() {
|
||||
transforms.addAll(new Translate(0, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package seng302.visualiser.cameras;
|
||||
|
||||
|
||||
public interface RaceCamera {
|
||||
|
||||
void zoomIn();
|
||||
|
||||
void zoomOut();
|
||||
|
||||
void panLeft();
|
||||
|
||||
void panRight();
|
||||
|
||||
void panUp();
|
||||
|
||||
void panDown();
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package seng302.visualiser.cameras;
|
||||
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.transform.Transform;
|
||||
import javafx.scene.transform.Translate;
|
||||
|
||||
public class TopDownCamera extends PerspectiveCamera implements RaceCamera {
|
||||
|
||||
ObservableList<Transform> transforms;
|
||||
|
||||
public TopDownCamera() {
|
||||
super(true);
|
||||
transforms = this.getTransforms();
|
||||
transforms.add(new Translate(0, 0, -125));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoomIn() {
|
||||
transforms.addAll(new Translate(0, 0, 1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zoomOut() {
|
||||
transforms.addAll(new Translate(0, 0, -1.5));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panLeft() {
|
||||
transforms.addAll(new Translate(-1, 0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panRight() {
|
||||
transforms.addAll(new Translate(1, 0, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panUp() {
|
||||
transforms.addAll(new Translate(0, -1, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void panDown() {
|
||||
transforms.addAll(new Translate(0, 1, 0));
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import seng302.model.RaceState;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Corner;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.discoveryServer.DiscoveryServerClient;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.GameView;
|
||||
import seng302.visualiser.controllers.cells.PlayerCell;
|
||||
@@ -30,7 +29,11 @@ import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
public class LobbyController implements Initializable {
|
||||
|
||||
@@ -83,25 +86,21 @@ public class LobbyController implements Initializable {
|
||||
serverName.setText(ViewManager.getInstance().getProperty("serverName"));
|
||||
mapName.setText(ViewManager.getInstance().getProperty("mapName"));
|
||||
|
||||
if (DiscoveryServerClient.getRoomCode() != null){
|
||||
setRoomCode(DiscoveryServerClient.getRoomCode());
|
||||
}
|
||||
|
||||
ViewManager.getInstance().getPlayerList().addListener((ListChangeListener<String>) c -> Platform.runLater(this::refreshPlayerList));
|
||||
|
||||
ViewManager.getInstance().getPlayerList().setAll(ViewManager.getInstance().getPlayerList().sorted());
|
||||
});
|
||||
|
||||
customizeButton.setOnMouseReleased(event -> {
|
||||
customizationDialog = createCustomizeDialog();
|
||||
Sounds.playButtonClick();
|
||||
customizationDialog.show();
|
||||
});
|
||||
|
||||
Platform.runLater(() -> {
|
||||
Integer playerId = ViewManager.getInstance().getGameClient().getServerThread().getClientId();
|
||||
|
||||
playersColor = Colors.getColor(playerId - 1);
|
||||
customizationDialog = createCustomizeDialog();
|
||||
|
||||
customizeButton.setOnMouseReleased(event -> {
|
||||
Sounds.playButtonClick();
|
||||
customizationDialog.show();
|
||||
});
|
||||
});
|
||||
|
||||
leaveLobbyButton.setOnMouseEntered(e -> Sounds.playHoverSound());
|
||||
@@ -131,6 +130,8 @@ public class LobbyController implements Initializable {
|
||||
controller.setPlayerName(this.playerBoats
|
||||
.get(ViewManager.getInstance().getGameClient().getServerThread().getClientId())
|
||||
.getBoatName());
|
||||
controller.setCurrentBoat(this.playerBoats.get(ViewManager.getInstance().getGameClient().getServerThread().getClientId())
|
||||
.getBoatType().toString());
|
||||
|
||||
return customizationDialog;
|
||||
}
|
||||
@@ -204,7 +205,7 @@ public class LobbyController implements Initializable {
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
getClass().getResource("/views/cells/PlayerCell.fxml"));
|
||||
|
||||
loader.setController(new PlayerCell(playerId, yacht.getBoatName(), yacht.getColour()));
|
||||
loader.setController(new PlayerCell(playerId, yacht));
|
||||
|
||||
try {
|
||||
pane = loader.load();
|
||||
@@ -244,8 +245,4 @@ public class LobbyController implements Initializable {
|
||||
public void closeCustomizationDialog() {
|
||||
customizationDialog.close();
|
||||
}
|
||||
|
||||
public void setRoomCode(String roomCode) {
|
||||
roomLabel.setText("Room#" + roomCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.SubScene;
|
||||
import javafx.scene.chart.LineChart;
|
||||
@@ -49,12 +47,10 @@ import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.model.ClientYacht.PowerUpListener;
|
||||
import seng302.model.RaceState;
|
||||
import seng302.model.mark.CompoundMark;
|
||||
import seng302.model.mark.Mark;
|
||||
import seng302.model.stream.xml.parser.RaceXMLData;
|
||||
import seng302.model.token.TokenType;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.GameView3D;
|
||||
import seng302.visualiser.controllers.annotations.ImportantAnnotationController;
|
||||
@@ -64,8 +60,6 @@ import seng302.visualiser.controllers.dialogs.FinishDialogController;
|
||||
import seng302.visualiser.fxObjects.ChatHistory;
|
||||
import seng302.visualiser.fxObjects.assets_2D.WindArrow;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatObject;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
||||
|
||||
/**
|
||||
* Controller class that manages the display of a race
|
||||
@@ -73,8 +67,6 @@ import seng302.visualiser.fxObjects.assets_3D.ModelType;
|
||||
public class RaceViewController extends Thread implements ImportantAnnotationDelegate {
|
||||
|
||||
private final int CHAT_LIMIT = 128;
|
||||
private static final Double ICON_BLINK_TIMEOUT_RATIO = 0.6;
|
||||
private static final Integer ICON_BLINK_PERIOD = 500;
|
||||
|
||||
@FXML
|
||||
private Pane basePane;
|
||||
@@ -95,7 +87,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
@FXML
|
||||
private Label timerLabel;
|
||||
@FXML
|
||||
private StackPane contentAnchorPane;
|
||||
private StackPane contentStackPane;
|
||||
|
||||
private GridPane contentGridPane;
|
||||
@FXML
|
||||
@@ -118,8 +110,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
private Label windSpeedLabel;
|
||||
@FXML
|
||||
private Label positionLabel, boatSpeedLabel, boatHeadingLabel;
|
||||
@FXML
|
||||
private ImageView velocityIcon, handlingIcon, windWalkerIcon, bumperIcon;
|
||||
|
||||
//Race Data
|
||||
private Map<Integer, ClientYacht> participants;
|
||||
@@ -144,8 +134,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
Sounds.stopMusic();
|
||||
Sounds.playRaceMusic();
|
||||
|
||||
finishScreenDialog = createFinishDialog();
|
||||
|
||||
// Load a default important annotation state
|
||||
//importantAnnotations = new ImportantAnnotationsState();
|
||||
|
||||
@@ -190,9 +178,10 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
// chatHistory.textProperty().addListener((obs, oldValue, newValue) -> {
|
||||
// chatHistory.setScrollTop(Double.MAX_VALUE);
|
||||
// });
|
||||
rvAnchorPane.setOnMouseClicked((event) ->
|
||||
rvAnchorPane.requestFocus()
|
||||
);
|
||||
|
||||
contentStackPane.setOnMouseClicked(event -> {
|
||||
contentStackPane.requestFocus();
|
||||
});
|
||||
|
||||
//Makes the chat history non transparent when clicked on
|
||||
chatInput.focusedProperty().addListener(new ChangeListener<Boolean>() {
|
||||
@@ -210,29 +199,29 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
|
||||
public void showFinishDialog(ArrayList<ClientYacht> finishedBoats) {
|
||||
raceState.setRaceStarted(false);
|
||||
finishDialogController.setFinishedBoats(finishedBoats);
|
||||
finishScreenDialog.show();
|
||||
createFinishDialog(finishedBoats);
|
||||
}
|
||||
|
||||
private JFXDialog createFinishDialog() {
|
||||
/**
|
||||
* Create finishScreenDialog and set up finishDialogController.
|
||||
*/
|
||||
private void createFinishDialog(ArrayList<ClientYacht> finishedBoats) {
|
||||
FXMLLoader dialog = new FXMLLoader(
|
||||
getClass().getResource("/views/dialogs/RaceFinishDialog.fxml"));
|
||||
|
||||
JFXDialog finishScreenDialog = null;
|
||||
|
||||
Platform.runLater(() -> {
|
||||
try {
|
||||
finishScreenDialog = new JFXDialog(contentAnchorPane, dialog.load(),
|
||||
finishScreenDialog = new JFXDialog(contentStackPane, dialog.load(),
|
||||
JFXDialog.DialogTransition.CENTER);
|
||||
finishDialogController = dialog.getController();
|
||||
finishDialogController.setFinishedBoats(finishedBoats);
|
||||
finishScreenDialog.show();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
finishDialogController = dialog.getController();
|
||||
|
||||
return finishScreenDialog;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void loadRace (
|
||||
Map<Integer, ClientYacht> participants, RaceXMLData raceData, RaceState raceState,
|
||||
ClientYacht player) {
|
||||
@@ -252,13 +241,11 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
}
|
||||
});
|
||||
|
||||
player.addPowerUpListener(this::displayPowerUpIcon);
|
||||
|
||||
updateOrder(raceState.getPlayerPositions());
|
||||
gameView = new GameView3D();
|
||||
// gameView.setFrameRateFXText(fpsDisplay);
|
||||
Platform.runLater(() -> {
|
||||
contentAnchorPane.getChildren().add(0, gameView.getAssets());
|
||||
contentStackPane.getChildren().add(0, gameView.getAssets());
|
||||
((SubScene) gameView.getAssets()).widthProperty()
|
||||
.bind(ViewManager.getInstance().getStage().widthProperty());
|
||||
((SubScene) gameView.getAssets()).heightProperty()
|
||||
@@ -292,62 +279,6 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the relevant icon, starts blinking it when it is close to turning off and then
|
||||
* switches it off after the tokens time out
|
||||
*
|
||||
* @param yacht The yacht only for which we are displaying the icon
|
||||
* @param tokenType The type of token, indicating what icon needs to be displayed
|
||||
*/
|
||||
private void displayPowerUpIcon(ClientYacht yacht, TokenType tokenType) {
|
||||
if (yacht == player) {
|
||||
final ImageView iconToDisplay;
|
||||
|
||||
switch (tokenType) {
|
||||
case BOOST:
|
||||
iconToDisplay = velocityIcon;
|
||||
break;
|
||||
case HANDLING:
|
||||
iconToDisplay = handlingIcon;
|
||||
break;
|
||||
case WIND_WALKER:
|
||||
iconToDisplay = windWalkerIcon;
|
||||
break;
|
||||
case BUMPER:
|
||||
iconToDisplay = bumperIcon;
|
||||
break;
|
||||
default:
|
||||
iconToDisplay = velocityIcon;
|
||||
}
|
||||
|
||||
//Turn icon on
|
||||
iconToDisplay.setVisible(true);
|
||||
|
||||
//Start blinking icon towards end
|
||||
Timer blinkingTimer = new Timer();
|
||||
blinkingTimer.schedule(new TimerTask() {
|
||||
Boolean isVisible = true;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
isVisible = !isVisible;
|
||||
iconToDisplay.setVisible(isVisible);
|
||||
}
|
||||
}, (int) (tokenType.getTimeout() * ICON_BLINK_TIMEOUT_RATIO), ICON_BLINK_PERIOD);
|
||||
|
||||
//Turn icon off after the time out
|
||||
Timer switchOffTimer = new Timer();
|
||||
switchOffTimer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
blinkingTimer.cancel();
|
||||
iconToDisplay.setVisible(false);
|
||||
}
|
||||
}, tokenType.getTimeout());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The important annotations have been changed, update this view
|
||||
*
|
||||
@@ -874,7 +805,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
||||
public String readChatInput() {
|
||||
String chat = chatInput.getText();
|
||||
chatInput.clear();
|
||||
rvAnchorPane.requestFocus();
|
||||
contentStackPane.requestFocus();
|
||||
return chat;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.input.KeyCode;
|
||||
@@ -23,10 +22,7 @@ import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import seng302.discoveryServer.DiscoveryServer;
|
||||
import seng302.gameServer.ServerDescription;
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
import seng302.discoveryServer.DiscoveryServerClient;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.ServerListener;
|
||||
import seng302.visualiser.ServerListenerDelegate;
|
||||
@@ -55,10 +51,6 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
||||
private JFXTextField serverHostName;
|
||||
@FXML
|
||||
private JFXTextField serverPortNumber;
|
||||
@FXML
|
||||
private JFXButton roomConnectButton;
|
||||
@FXML
|
||||
private JFXTextField roomNumber;
|
||||
//---------FXML END---------//
|
||||
|
||||
private Label noServersFound;
|
||||
@@ -72,17 +64,6 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
||||
// Set Event Bindings
|
||||
connectButton.setOnMouseEntered(event -> Sounds.playHoverSound());
|
||||
serverListHostButton.setOnMouseEntered(event -> Sounds.playHoverSound());
|
||||
|
||||
roomConnectButton.setOnMouseReleased(event -> {
|
||||
connectToRoomCode(roomNumber.getText());
|
||||
Sounds.playButtonClick();
|
||||
});
|
||||
roomNumber.setOnKeyPressed(event -> {
|
||||
if (event.getCode().equals(KeyCode.ENTER)) {
|
||||
connectToRoomCode(roomNumber.getText());
|
||||
}
|
||||
});
|
||||
|
||||
connectButton.setOnMouseReleased(event -> {
|
||||
attemptToDirectConnect();
|
||||
Sounds.playButtonClick();
|
||||
@@ -131,16 +112,23 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
||||
serverListVBox.getChildren().add(noServersFound);
|
||||
|
||||
// Set up dialog for server creation
|
||||
serverListHostButton.setOnAction(action -> {
|
||||
showServerCreationDialog();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows Server Creation Dialog when "Host" button is clicked.
|
||||
*/
|
||||
private void showServerCreationDialog() {
|
||||
Platform.runLater(() -> {
|
||||
FXMLLoader dialogContent = new FXMLLoader(getClass().getResource(
|
||||
"/views/dialogs/ServerCreationDialog.fxml"));
|
||||
try {
|
||||
JFXDialog dialog = new JFXDialog(serverListMainStackPane, dialogContent.load(),
|
||||
DialogTransition.CENTER);
|
||||
serverListHostButton.setOnAction(action -> {
|
||||
dialog.show();
|
||||
Sounds.playButtonClick();
|
||||
});
|
||||
} catch (IOException e) {
|
||||
logger.warn("Could not create Server Creation Dialog.");
|
||||
}
|
||||
@@ -169,24 +157,6 @@ public class ServerListController implements Initializable, ServerListenerDelega
|
||||
return hostNameValid && portNumberValid;
|
||||
}
|
||||
|
||||
private void connectToRoomCode(String roomCode){
|
||||
try {
|
||||
ServerListing serverListing = new DiscoveryServerClient().getServerForRoomCode(roomCode);
|
||||
ViewManager.getInstance().getGameClient().runAsClient(serverListing.getAddress(), serverListing.getPortNumber());
|
||||
}
|
||||
catch (java.net.ConnectException e){
|
||||
//TODO Add proper dialog
|
||||
logger.warn("Couldn't connect to discovery server");
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setHeaderText("Couldn't connect to discovery server");
|
||||
alert.setContentText("Couldn't connect to " + DiscoveryServer.DISCOVERY_SERVER);
|
||||
alert.showAndWait();
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.warn("Error discovering room code");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects the user to a lobby via the Direct Connect form.
|
||||
*/
|
||||
|
||||
@@ -2,6 +2,9 @@ package seng302.visualiser.controllers;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXDecorator;
|
||||
import com.jfoenix.controls.JFXDialog;
|
||||
import com.jfoenix.controls.JFXDialog.DialogTransition;
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import com.jfoenix.svg.SVGGlyph;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
@@ -15,6 +18,7 @@ import javafx.scene.Scene;
|
||||
import javafx.scene.SceneAntialiasing;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
@@ -23,6 +27,7 @@ import seng302.gameServer.ServerAdvertiser;
|
||||
import seng302.utilities.BonjourInstallChecker;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.GameClient;
|
||||
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
|
||||
|
||||
public class ViewManager {
|
||||
|
||||
@@ -32,12 +37,9 @@ public class ViewManager {
|
||||
private HashMap<String, String> properties; //TODO is this the best way to do this??
|
||||
private ObservableList<String> playerList;
|
||||
private Logger logger = LoggerFactory.getLogger(ViewManager.class);
|
||||
|
||||
public Stage getStage() {
|
||||
return stage;
|
||||
}
|
||||
|
||||
private Stage stage;
|
||||
private JFXSnackbar jfxSnackbar;
|
||||
private JFXDialog keyBindingDialog;
|
||||
|
||||
private ViewManager() {
|
||||
properties = new HashMap<>();
|
||||
@@ -99,6 +101,8 @@ public class ViewManager {
|
||||
gameClient.stopGame();
|
||||
System.exit(0);
|
||||
});
|
||||
|
||||
jfxSnackbar = new JFXSnackbar(decorator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,12 +123,31 @@ public class ViewManager {
|
||||
//Get the button box
|
||||
HBox btns = (HBox) decorator.getChildren().get(0);
|
||||
|
||||
//Create settings button -- [WIP]
|
||||
JFXButton btnKeyBinding = new JFXButton();
|
||||
btnKeyBinding.setText(" Key Bindings");
|
||||
btnKeyBinding.setStyle("-fx-text-fill:#fff");
|
||||
btnKeyBinding.getStyleClass().add("jfx-decorator-button");
|
||||
btnKeyBinding.setCursor(Cursor.HAND);
|
||||
btnKeyBinding.setFocusTraversable(false);
|
||||
|
||||
btnKeyBinding.setOnMouseClicked(event -> Platform.runLater(() -> {
|
||||
try {
|
||||
if (!checkDialogOpened(decorator.getChildren())) {
|
||||
showKeyBindingDialog();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.warn("Something went wrong when opening key bind dialog");
|
||||
}
|
||||
}));
|
||||
|
||||
//Create new button
|
||||
JFXButton btnMute = new JFXButton();
|
||||
btnMute.setText(" Toggle Sound");
|
||||
btnMute.setStyle("-fx-text-fill:#fff");
|
||||
btnMute.getStyleClass().add("jfx-decorator-button");
|
||||
btnMute.setCursor(Cursor.HAND);
|
||||
btnMute.setFocusTraversable(false);
|
||||
|
||||
//Create Graphics
|
||||
SVGGlyph spacer = new SVGGlyph(0, "SPACER", "", Color.WHITE);
|
||||
@@ -134,9 +157,13 @@ public class ViewManager {
|
||||
SVGGlyph volumeOff = new SVGGlyph(0, "VOLUME_ON",
|
||||
"M13.5,9 C13.5,7.2 12.5,5.7 11,5 L11,7.2 L13.5,9.7 L13.5,9 L13.5,9 Z M16,9 C16,9.9 15.8,10.8 15.5,11.6 L17,13.1 C17.7,11.9 18,10.4 18,8.9 C18,4.6 15,1 11,0.1 L11,2.2 C13.9,3.2 16,5.8 16,9 L16,9 Z M1.3,0 L0,1.3 L4.7,6 L0,6 L0,12 L4,12 L9,17 L9,10.3 L13.3,14.6 C12.6,15.1 11.9,15.5 11,15.8 L11,17.9 C12.4,17.6 13.6,17 14.7,16.1 L16.7,18.1 L18,16.8 L9,7.8 L1.3,0 L1.3,0 Z M9,1 L6.9,3.1 L9,5.2 L9,1 L9,1 Z",
|
||||
Color.WHITE);
|
||||
SVGGlyph keyBindingGlyph = new SVGGlyph(0, "KEY_BINDING",
|
||||
"M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z",
|
||||
Color.WHITE);
|
||||
volumeOn.setSize(16, 16);
|
||||
volumeOff.setSize(16, 16);
|
||||
spacer.setSize(40, 16);
|
||||
keyBindingGlyph.setSize(24, 16);
|
||||
|
||||
// Determine which graphic should go on the button
|
||||
if (Sounds.isMusicMuted() && Sounds.isSoundEffectsMuted()) {
|
||||
@@ -145,9 +172,12 @@ public class ViewManager {
|
||||
btnMute.setGraphic(volumeOn);
|
||||
}
|
||||
|
||||
btnKeyBinding.setGraphic(keyBindingGlyph);
|
||||
|
||||
// Add Buttons
|
||||
btns.getChildren().add(0, spacer);
|
||||
btns.getChildren().add(0, btnMute);
|
||||
btns.getChildren().add(0, btnKeyBinding);
|
||||
btnMute.setOnAction((action) -> {
|
||||
Sounds.toggleAllSounds();
|
||||
if (btnMute.getGraphic().equals(volumeOff)) {
|
||||
@@ -159,6 +189,63 @@ public class ViewManager {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively find JFXDialog given a starting node. Will traverse children of StackPane.
|
||||
*
|
||||
* @param nodes children nodes to be check.
|
||||
* @return true if node contains JFXDialog.
|
||||
*/
|
||||
private Boolean checkDialogOpened(ObservableList<Node> nodes) {
|
||||
boolean foundJFXDialog = false;
|
||||
for (Node node : nodes) {
|
||||
if (node instanceof JFXDialog) {
|
||||
return true;
|
||||
} else if (node instanceof StackPane) {
|
||||
foundJFXDialog = checkDialogOpened(((StackPane) node).getChildren());
|
||||
}
|
||||
}
|
||||
return foundJFXDialog;
|
||||
}
|
||||
|
||||
private void showKeyBindingDialog() throws IOException {
|
||||
FXMLLoader dialogContent = new FXMLLoader(getClass().getResource(
|
||||
"/views/dialogs/KeyBindingDialog.fxml"));
|
||||
for (Node node : decorator.getChildren()) {
|
||||
if (node instanceof StackPane) {
|
||||
keyBindingDialog = new JFXDialog((StackPane) node,
|
||||
dialogContent.load(),
|
||||
DialogTransition.CENTER);
|
||||
|
||||
KeyBindingDialogController keyBindingDialogController = dialogContent
|
||||
.getController();
|
||||
keyBindingDialogController.setGameClient(this.gameClient);
|
||||
keyBindingDialog.show();
|
||||
Sounds.playButtonClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeKeyBindingDialog() {
|
||||
keyBindingDialog.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a snackbar at the bottom of the app for 1 second.
|
||||
*
|
||||
* @param snackbarText text to be displayed.
|
||||
*/
|
||||
public void showSnackbar(String snackbarText, boolean isWarning) {
|
||||
if (isWarning) {
|
||||
decorator.getStylesheets()
|
||||
.add(getClass().getResource("/css/dialogs/Snackbar.css").toExternalForm());
|
||||
} else {
|
||||
if (decorator.getStylesheets().size() > 1) {
|
||||
decorator.getStylesheets().remove(1);
|
||||
}
|
||||
}
|
||||
jfxSnackbar.show(snackbarText, 1500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a PC has compatibility with the bonjour protocol for server detection.
|
||||
*/
|
||||
@@ -221,6 +308,7 @@ public class ViewManager {
|
||||
|
||||
/**
|
||||
* Change the view to the Lobby Screen
|
||||
*
|
||||
* @param disableReadyButton Boolean value so that clients can't try start a game.
|
||||
* @return A LobbyController object for the Lobby Screen.
|
||||
*/
|
||||
@@ -233,9 +321,8 @@ public class ViewManager {
|
||||
logger.error("Could not load lobby view");
|
||||
}
|
||||
|
||||
LobbyController lobbyController = loader.getController();
|
||||
|
||||
if (disableReadyButton) {
|
||||
LobbyController lobbyController = loader.getController();
|
||||
lobbyController.disableReadyButton();
|
||||
}
|
||||
|
||||
@@ -244,8 +331,10 @@ public class ViewManager {
|
||||
|
||||
/**
|
||||
* Sets up the view for the race. Creating a new decorator and destroying the old one.
|
||||
*
|
||||
* @return A RaceViewController for the race view screen.
|
||||
*/
|
||||
|
||||
public RaceViewController loadRaceView() {
|
||||
FXMLLoader loader = loadFxml("/views/RaceView.fxml");
|
||||
// have to create a new stage and set the race view maximized as JFoenix decorator has
|
||||
@@ -267,17 +356,10 @@ public class ViewManager {
|
||||
scene.setOnKeyPressed(gameClient::keyPressed);
|
||||
scene.setOnKeyReleased(gameClient::keyReleased);
|
||||
|
||||
// uncomment to make it full screen
|
||||
// Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
|
||||
// stage.setX(visualBounds.getMinX());
|
||||
// stage.setY(visualBounds.getMinY());
|
||||
// stage.setWidth(visualBounds.getWidth());
|
||||
// stage.setHeight(visualBounds.getHeight());
|
||||
// stage.setMaximized(true);
|
||||
// stage.setFullScreen(true);
|
||||
|
||||
stage.setMinHeight(500);
|
||||
stage.setMinWidth(800);
|
||||
stage.setTitle("Party Parrots At Sea");
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/PP.png")));
|
||||
stage.setOnCloseRequest(e -> closeAll());
|
||||
stage.setScene(scene);
|
||||
stage.show();
|
||||
@@ -296,4 +378,9 @@ public class ViewManager {
|
||||
|
||||
return loader.getController();
|
||||
}
|
||||
|
||||
public Stage getStage() {
|
||||
return stage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatModel;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||
@@ -24,11 +25,13 @@ public class PlayerCell {
|
||||
private String name;
|
||||
private Color boatColor;
|
||||
private Integer playerId;
|
||||
private BoatMeshType boatType;
|
||||
|
||||
public PlayerCell(Integer playerId, String playerName, Color color) {
|
||||
public PlayerCell(Integer playerId, ClientYacht yacht) {
|
||||
this.playerId = playerId;
|
||||
this.name = playerName;
|
||||
this.boatColor = color;
|
||||
this.name = yacht.getBoatName();
|
||||
this.boatColor = yacht.getColour();
|
||||
this.boatType = yacht.getBoatType();
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
@@ -37,7 +40,7 @@ public class PlayerCell {
|
||||
// Add Rotating Boat to Player Cell with players color on it.
|
||||
Group group = new Group();
|
||||
boatPane.getChildren().add(group);
|
||||
BoatModel bo = ModelFactory.boatIconView(BoatMeshType.DINGHY, this.boatColor);
|
||||
BoatModel bo = ModelFactory.boatIconView(boatType, boatColor);
|
||||
group.getChildren().add(bo.getAssets());
|
||||
}
|
||||
|
||||
|
||||
@@ -6,15 +6,25 @@ import com.jfoenix.controls.JFXTextField;
|
||||
import com.jfoenix.validation.RequiredFieldValidator;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.PointLight;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.BackgroundFill;
|
||||
import javafx.scene.layout.CornerRadii;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.paint.Color;
|
||||
import seng302.gameServer.messages.CustomizeRequestType;
|
||||
import seng302.utilities.Sounds;
|
||||
import seng302.visualiser.ClientToServerThread;
|
||||
import seng302.visualiser.controllers.LobbyController;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatModel;
|
||||
import seng302.visualiser.fxObjects.assets_3D.ModelFactory;
|
||||
import seng302.visualiser.validators.FieldLengthValidator;
|
||||
import seng302.visualiser.validators.ValidationTools;
|
||||
|
||||
@@ -24,23 +34,35 @@ public class BoatCustomizeController implements Initializable{
|
||||
@FXML
|
||||
private JFXColorPicker colorPicker;
|
||||
@FXML
|
||||
private ProgressBar speedBar;
|
||||
@FXML
|
||||
private ProgressBar accelBar;
|
||||
@FXML
|
||||
private ProgressBar handleBar;
|
||||
@FXML
|
||||
private JFXButton submitBtn;
|
||||
@FXML
|
||||
private JFXTextField boatName;
|
||||
@FXML
|
||||
void colorChanged(ActionEvent event) {
|
||||
Color color = colorPicker.getValue();
|
||||
private Pane boatPane;
|
||||
@FXML
|
||||
void colorChanged() {
|
||||
refreshBoat();
|
||||
}
|
||||
//---------FXML END---------//
|
||||
|
||||
private ClientToServerThread socketThread;
|
||||
private LobbyController lobbyController;
|
||||
private BoatMeshType currentBoat;
|
||||
private Double maxSpeedMultiplier = 1.0;
|
||||
private Double maxTurnRateMultiplier = 1.0;
|
||||
private Double maxAccelerationMultiplier = 1.0;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
||||
socketThread = ViewManager.getInstance().getGameClient().getServerThread();
|
||||
|
||||
findMaxStats();
|
||||
RequiredFieldValidator playerNameReqValidator = new RequiredFieldValidator();
|
||||
playerNameReqValidator.setMessage("Player name required.");
|
||||
|
||||
@@ -48,6 +70,8 @@ public class BoatCustomizeController implements Initializable{
|
||||
playerNameLengthValidator.setMessage("Player name too long.");
|
||||
|
||||
boatName.setValidators(playerNameLengthValidator, playerNameReqValidator);
|
||||
boatPane.setBackground(
|
||||
new Background(new BackgroundFill(Color.SKYBLUE, CornerRadii.EMPTY, Insets.EMPTY)));
|
||||
|
||||
submitBtn.setOnMouseReleased(event -> {
|
||||
Sounds.playButtonClick();
|
||||
@@ -78,7 +102,10 @@ public class BoatCustomizeController implements Initializable{
|
||||
colorArray[2] = (byte) blue;
|
||||
|
||||
socketThread.sendCustomizationRequest(CustomizeRequestType.COLOR, colorArray);
|
||||
socketThread.sendCustomizationRequest(CustomizeRequestType.SHAPE, currentBoat.toString().getBytes());
|
||||
lobbyController.closeCustomizationDialog();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,4 +120,61 @@ public class BoatCustomizeController implements Initializable{
|
||||
public void setParentController(LobbyController lobbyController){
|
||||
this.lobbyController = lobbyController;
|
||||
}
|
||||
|
||||
public void setCurrentBoat(String boatType) {
|
||||
currentBoat = BoatMeshType.valueOf(boatType);
|
||||
displayCurrentBoat();
|
||||
refreshStatBars(currentBoat);
|
||||
}
|
||||
|
||||
public void nextBoat() {
|
||||
currentBoat = BoatMeshType.getNextBoatType(currentBoat);
|
||||
displayCurrentBoat();
|
||||
refreshStatBars(currentBoat);
|
||||
}
|
||||
|
||||
public void prevBoat() {
|
||||
currentBoat = BoatMeshType.getPrevBoatType(currentBoat);
|
||||
displayCurrentBoat();
|
||||
refreshStatBars(currentBoat);
|
||||
|
||||
}
|
||||
|
||||
private void displayCurrentBoat() {
|
||||
boatPane.getChildren().clear();
|
||||
Group group = new Group();
|
||||
boatPane.getChildren().add(group);
|
||||
BoatModel bo = ModelFactory.boatCustomiseView(currentBoat, colorPicker.getValue());
|
||||
group.getChildren().add(bo.getAssets());
|
||||
group.getChildren().add(new PointLight());
|
||||
}
|
||||
|
||||
private void refreshBoat() {
|
||||
boatPane.getChildren().clear();
|
||||
Group group = new Group();
|
||||
boatPane.getChildren().add(group);
|
||||
BoatModel bo = ModelFactory.boatCustomiseView(currentBoat, colorPicker.getValue());
|
||||
group.getChildren().add(bo.getAssets());
|
||||
refreshStatBars(currentBoat);
|
||||
}
|
||||
|
||||
private void findMaxStats() {
|
||||
for (BoatMeshType bmt: BoatMeshType.values()) {
|
||||
if (bmt.turnStep > maxTurnRateMultiplier) {
|
||||
maxTurnRateMultiplier = bmt.turnStep;
|
||||
}
|
||||
if (bmt.maxSpeedMultiplier > maxSpeedMultiplier) {
|
||||
maxSpeedMultiplier = bmt.maxSpeedMultiplier;
|
||||
}
|
||||
if (bmt.accelerationMultiplier > maxAccelerationMultiplier) {
|
||||
maxAccelerationMultiplier = bmt.accelerationMultiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshStatBars(BoatMeshType bo) {
|
||||
speedBar.setProgress((bo.maxSpeedMultiplier) / maxSpeedMultiplier);
|
||||
accelBar.setProgress(bo.accelerationMultiplier / maxAccelerationMultiplier);
|
||||
handleBar.setProgress(bo.turnStep / maxTurnRateMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
package seng302.visualiser.controllers.dialogs;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXToggleButton;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import seng302.model.GameKeyBind;
|
||||
import seng302.model.KeyAction;
|
||||
import seng302.visualiser.GameClient;
|
||||
import seng302.visualiser.controllers.ViewManager;
|
||||
|
||||
public class KeyBindingDialogController implements Initializable {
|
||||
|
||||
//--------FXML BEGIN--------//
|
||||
@FXML
|
||||
private Label keyBindingDialogHeader;
|
||||
@FXML
|
||||
private Label closeLabel;
|
||||
@FXML
|
||||
private JFXButton zoomInbtn;
|
||||
@FXML
|
||||
private JFXButton zoomOutBtn;
|
||||
@FXML
|
||||
private JFXButton vmgBtn;
|
||||
@FXML
|
||||
private JFXButton sailInOutBtn;
|
||||
@FXML
|
||||
private JFXButton tackGybeBtn;
|
||||
@FXML
|
||||
private JFXButton upwindBtn;
|
||||
@FXML
|
||||
private JFXButton downwindBtn;
|
||||
@FXML
|
||||
private JFXButton resetBtn;
|
||||
@FXML
|
||||
private Label upwindLabel;
|
||||
@FXML
|
||||
private Label downwindLabel;
|
||||
@FXML
|
||||
private JFXToggleButton turningToggle;
|
||||
//---------FXML END---------//
|
||||
|
||||
private GameKeyBind gameKeyBind;
|
||||
private List<JFXButton> buttons = new ArrayList<>();
|
||||
private Map<Button, KeyAction> buttonActionMap;
|
||||
private GameClient gameClient; // to send turning mode packet
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
gameKeyBind = GameKeyBind.getInstance();
|
||||
buttons = new ArrayList<>();
|
||||
Collections.addAll(buttons,
|
||||
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn);
|
||||
bindButtonWithAction();
|
||||
loadKeyBind();
|
||||
|
||||
buttons.forEach(button -> {
|
||||
button.setOnMouseEntered(event -> mouseEnter(button));
|
||||
button.setOnMousePressed(event -> buttonPressed(button));
|
||||
button.setOnMouseExited(event -> mouseExit(button));
|
||||
button.setOnKeyPressed(event -> keyPressed(event, button));
|
||||
});
|
||||
|
||||
turningToggle.setOnMouseClicked(event -> toggleTurningMode());
|
||||
|
||||
resetBtn.setOnMouseClicked(event -> {
|
||||
gameKeyBind.setToDefault();
|
||||
loadKeyBind();
|
||||
});
|
||||
|
||||
closeLabel.setOnMouseClicked(event -> ViewManager.getInstance().closeKeyBindingDialog());
|
||||
|
||||
keyBindingDialogHeader.setFocusTraversable(true);
|
||||
keyBindingDialogHeader.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set buttons' label according to GameKeyBind settings
|
||||
*/
|
||||
private void loadKeyBind() {
|
||||
buttons.forEach(
|
||||
button -> button
|
||||
.setText(gameKeyBind.getKeyCode(buttonActionMap.get(button)).getName()));
|
||||
turningToggle.setSelected(gameKeyBind.isContinuouslyTurning());
|
||||
if (gameKeyBind.isContinuouslyTurning()) {
|
||||
upwindLabel.setText("ClOCKWISE TURNING");
|
||||
downwindLabel.setText("ANTICLOCKWISE TURNING");
|
||||
} else {
|
||||
upwindLabel.setText("UPWIND");
|
||||
downwindLabel.setText("DOWNWIND");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind buttons with specific action in a map.
|
||||
*/
|
||||
private void bindButtonWithAction() {
|
||||
buttonActionMap = new HashMap<>();
|
||||
for (int i = 0; i < 7; i++) {
|
||||
buttonActionMap.put(buttons.get(i), KeyAction.getType(i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt success / failure message for reassigning key action
|
||||
*/
|
||||
private void showSnackBar(String message, Boolean isWarning) {
|
||||
ViewManager.getInstance().showSnackbar(message, isWarning);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a mouse enters the button, the color and font size should change to highlight
|
||||
* @param button
|
||||
*/
|
||||
private void mouseEnter(Button button) {
|
||||
button.setStyle(""
|
||||
+ "-fx-background-color: -fx-pp-theme-color;"
|
||||
+ "-fx-text-fill: -fx-pp-front-color;"
|
||||
+ "-fx-font-size: 15;");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt "press key..." to inform users assign a new key bind by pressing a key
|
||||
* @param button
|
||||
*/
|
||||
private void buttonPressed(Button button) {
|
||||
button.setText("PRESS KEY...");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When mouse leaves the button, return the button to the normal state in terms of text,
|
||||
* color and font size
|
||||
* @param button
|
||||
*/
|
||||
private void mouseExit(Button button) {
|
||||
button.setText(GameKeyBind.getInstance().getKeyCode(buttonActionMap.get(button)).getName());
|
||||
button.setStyle(""
|
||||
+ "-fx-background-color: -fx-pp-front-color; "
|
||||
+ "-fx-text-fill: -fx-pp-theme-color; "
|
||||
+ "-fx-font-size: 13;");
|
||||
}
|
||||
|
||||
/**
|
||||
* When a key is pressed, check if the new binding conflicts to any existed settings, if not
|
||||
* assign the selected action with the new key binding to GameKeyBind.
|
||||
* @param event
|
||||
* @param button
|
||||
*/
|
||||
private void keyPressed(KeyEvent event, Button button) {
|
||||
event.consume();
|
||||
KeyAction buttonAction = buttonActionMap.get(button);
|
||||
if (gameKeyBind.bindKeyToAction(event.getCode(), buttonAction)) {
|
||||
showSnackBar(button.getId() + " is set to " + event.getCode().getName(), false);
|
||||
button.setText(gameKeyBind.getKeyCode(buttonAction).getName());
|
||||
} else {
|
||||
loadKeyBind();
|
||||
showSnackBar(event.getCode().getName() + " is already in use", true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the turning mode is toggled, update gameKeyBind and send out packet to notify the server
|
||||
*/
|
||||
private void toggleTurningMode() {
|
||||
gameKeyBind.toggleTurningMode();
|
||||
gameClient.sendToggleTurningModePacket();
|
||||
loadKeyBind();
|
||||
}
|
||||
|
||||
public void setGameClient(GameClient gameClient) {
|
||||
this.gameClient = gameClient;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,21 +2,59 @@ package seng302.visualiser.fxObjects.assets_3D;
|
||||
|
||||
/**
|
||||
* Enum for boat meshes. Enum values should be of the form :
|
||||
* ENUM_VALUE (hull file, mast file, Y offset of mast CoR from origin, sail file, Y offset of sail CoR from origin)
|
||||
* ENUM_VALUE (hull file, mast file, Y offset of mast CoR from origin, sail file, Y offset of sail CoR from origin, jib file, fixed sail)
|
||||
* Files must be valid .stl files.
|
||||
*/
|
||||
public enum BoatMeshType {
|
||||
|
||||
DINGHY ("dinghy_hull.stl", "dinghy_mast.stl", -1.36653, "dinghy_sail.stl", -1.36653);
|
||||
DINGHY("dinghy_hull.stl", "dinghy_mast.stl", 1.36653, "dinghy_sail.stl", 1.36653, null, false, 1.8, 1.0, 1.0),
|
||||
CATAMARAN("catamaran_hull.stl", "catamaran_mast.stl", 0.997, "catamaran_sail.stl",
|
||||
0.997, null, false, 1.0, 1.4, 2.0),
|
||||
PIRATE_SHIP("pirateship_hull.stl", "pirateship_mast.stl", -0.5415, "pirateship_mainsail.stl",
|
||||
-0.5415, "pirateship_frontsail.stl", true, 1.2, 1.6, 1.2);
|
||||
|
||||
final String hullFile, mastFile, sailFile;
|
||||
final String hullFile, mastFile, sailFile, jibFile;
|
||||
final double mastOffset, sailOffset;
|
||||
public final double maxSpeedMultiplier;
|
||||
public final double accelerationMultiplier;
|
||||
public final double turnStep;
|
||||
final boolean fixedSail;
|
||||
final static BoatMeshType[] boatTypes = new BoatMeshType[]{DINGHY, CATAMARAN, PIRATE_SHIP};
|
||||
|
||||
BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile, double sailOffset) {
|
||||
BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile,
|
||||
double sailOffset, String jibFile, boolean fixedSail, double maxSpeedMultiplier, double accelerationMultiplier, double turnStep) {
|
||||
this.hullFile = hullFile;
|
||||
this.mastFile = mastFile;
|
||||
this.mastOffset = mastOffset;
|
||||
this.sailFile = sailFile;
|
||||
this.sailOffset = sailOffset;
|
||||
this.jibFile = jibFile;
|
||||
this.fixedSail = fixedSail;
|
||||
this.maxSpeedMultiplier = maxSpeedMultiplier;
|
||||
this.accelerationMultiplier = accelerationMultiplier;
|
||||
this.turnStep = turnStep;
|
||||
}
|
||||
|
||||
|
||||
public static BoatMeshType getNextBoatType(BoatMeshType boatType) {
|
||||
for (int i = 0; i < boatTypes.length; i++) {
|
||||
if (i == boatTypes.length -1) {
|
||||
return boatTypes[0];
|
||||
} else if (boatType == boatTypes[i]) {
|
||||
return boatTypes[i+1];
|
||||
}
|
||||
}
|
||||
return boatType;
|
||||
}
|
||||
|
||||
public static BoatMeshType getPrevBoatType(BoatMeshType boatType) {
|
||||
for (int i = 0; i < boatTypes.length; i++) {
|
||||
if (i == 0 && boatType == boatTypes[i]) {
|
||||
return boatTypes[boatTypes.length -1];
|
||||
} else if (boatType == boatTypes[i]) {
|
||||
return boatTypes[i-1];
|
||||
}
|
||||
}
|
||||
return boatType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,15 +34,17 @@ public class BoatModel extends Model {
|
||||
* @param degrees The rotation of the sail in degrees
|
||||
*/
|
||||
public void rotateSail(double degrees) {
|
||||
if (!meshType.fixedSail) {
|
||||
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))
|
||||
new Rotate(degrees, 0, -meshType.mastOffset, 0, new Point3D(0, 0, 1))
|
||||
);
|
||||
sail.getTransforms().setAll(
|
||||
new Rotate(degrees, -meshType.sailOffset, 0,0, new Point3D(0, 0, 1))
|
||||
new Rotate(degrees, 0, -meshType.sailOffset,0, new Point3D(0, 0, 1))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void hideSail() {
|
||||
getMeshViewChild(SAIL_INDEX).setVisible(false);
|
||||
@@ -69,4 +71,8 @@ public class BoatModel extends Model {
|
||||
private MeshView getMeshViewChild(int index) {
|
||||
return (MeshView) assets.getChildren().get(index);
|
||||
}
|
||||
|
||||
public BoatMeshType getMeshType() {
|
||||
return meshType;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import javafx.scene.transform.Rotate;
|
||||
/**
|
||||
* BoatGroup is a javafx group that by default contains a graphical objects for representing a 2
|
||||
* dimensional boat. It contains a single polygon for the boat, a group of lines to show it's path,
|
||||
* a wake object and two text labels to annotate the boat teams name and the boats velocity. The
|
||||
* a wake object and two text labels to annotate the boat teams name and the boatTypes velocity. The
|
||||
* boat will update it's position onscreen everytime UpdatePosition is called unless the window is
|
||||
* minimized in which case it attempts to store animations and apply them when the window is
|
||||
* maximised.
|
||||
@@ -28,15 +28,15 @@ public class BoatObject extends Group {
|
||||
private Group wake;
|
||||
private Color colour = Color.BLACK;
|
||||
private Boolean isSelected = false;
|
||||
private Rotate rotation = new Rotate(0,0,1);
|
||||
private Rotate rotation = new Rotate(0, new Point3D(0,0,1));
|
||||
|
||||
private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Creates a BoatGroup with the default triangular boat polygon.
|
||||
*/
|
||||
public BoatObject() {
|
||||
boatAssets = ModelFactory.boatGameView(BoatMeshType.DINGHY, colour);
|
||||
public BoatObject(BoatMeshType boatMeshType) {
|
||||
boatAssets = ModelFactory.boatGameView(boatMeshType, colour);
|
||||
boatAssets.hideSail();
|
||||
boatAssets.getAssets().getTransforms().addAll(
|
||||
rotation
|
||||
@@ -66,8 +66,6 @@ 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(boatAssets.getAssets().getLayoutX() - x);
|
||||
Double dy = Math.abs(boatAssets.getAssets().getLayoutY() - y);
|
||||
Platform.runLater(() -> {
|
||||
rotateTo(rotation, sailIn, windDir);
|
||||
this.layoutXProperty().setValue(x);
|
||||
|
||||
@@ -7,6 +7,7 @@ import javafx.geometry.Point3D;
|
||||
import javafx.scene.AmbientLight;
|
||||
import javafx.scene.CacheHint;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.PointLight;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.PhongMaterial;
|
||||
import javafx.scene.shape.Circle;
|
||||
@@ -18,7 +19,7 @@ import javafx.scene.transform.Translate;
|
||||
|
||||
|
||||
/**
|
||||
* Factory class for creating 3D models of boats.
|
||||
* Factory class for creating 3D models of boatTypes.
|
||||
*/
|
||||
public class ModelFactory {
|
||||
|
||||
@@ -51,6 +52,35 @@ public class ModelFactory {
|
||||
return bo;
|
||||
}
|
||||
|
||||
public static BoatModel boatCustomiseView(BoatMeshType boatType, Color primaryColour) {
|
||||
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
|
||||
final Rotate animationRotate = new Rotate(0, new Point3D(0,0,1));
|
||||
boatAssets.getTransforms().addAll(
|
||||
new Scale(8.0, 8.0, 8.0),
|
||||
new Rotate(-70, new Point3D(1,0,0)),
|
||||
new Translate(16,50, 1),
|
||||
animationRotate
|
||||
);
|
||||
|
||||
boatAssets.getTransforms().add(animationRotate);
|
||||
BoatModel bo = new BoatModel(boatAssets, null, boatType);
|
||||
bo.rotateSail(45);
|
||||
|
||||
bo.setAnimation(new AnimationTimer() {
|
||||
double boatAngle = 0;
|
||||
Rotate rotate = animationRotate;
|
||||
@Override
|
||||
public void handle(long now) {
|
||||
boatAngle += 0.5;
|
||||
rotate.setAngle(boatAngle);
|
||||
}
|
||||
});
|
||||
boatAssets.getChildren().addAll(
|
||||
new AmbientLight()
|
||||
);
|
||||
return bo;
|
||||
}
|
||||
|
||||
public static BoatModel boatRotatingView(BoatMeshType boatType, Color primaryColour) {
|
||||
Group boatAssets = getUnmodifiedBoatModel(boatType, primaryColour);
|
||||
boatAssets.getTransforms().addAll(
|
||||
@@ -84,20 +114,29 @@ public class ModelFactory {
|
||||
}
|
||||
|
||||
private static Group getUnmodifiedBoatModel(BoatMeshType boatType, Color primaryColour) {
|
||||
|
||||
Group boatAssets = new Group();
|
||||
MeshView hull = importFile(boatType.hullFile);
|
||||
MeshView hull = importSTL(boatType.hullFile);
|
||||
hull.setMaterial(new PhongMaterial(primaryColour));
|
||||
MeshView mast = importFile(boatType.mastFile);
|
||||
MeshView mast = importSTL(boatType.mastFile);
|
||||
mast.setMaterial(new PhongMaterial(primaryColour));
|
||||
MeshView sail = importFile(boatType.sailFile);
|
||||
MeshView sail = importSTL(boatType.sailFile);
|
||||
sail.setMaterial(new PhongMaterial(Color.WHITE));
|
||||
|
||||
if (boatType.jibFile != null) {
|
||||
MeshView jib = importSTL(boatType.jibFile);
|
||||
sail.setMaterial(new PhongMaterial(Color.WHITE));
|
||||
boatAssets.getChildren().addAll(hull, mast, sail, jib);
|
||||
} else {
|
||||
boatAssets.getChildren().addAll(hull, mast, sail);
|
||||
}
|
||||
|
||||
return boatAssets;
|
||||
}
|
||||
|
||||
private static MeshView importFile(String fileName) {
|
||||
private static MeshView importSTL(String fileName) {
|
||||
StlMeshImporter importer = new StlMeshImporter();
|
||||
importer.read(ModelFactory.class.getResource("/meshes/" + fileName));
|
||||
importer.read(ModelFactory.class.getResource("/meshes/boatSTLs/" + fileName));
|
||||
MeshView importedFile = new MeshView(importer.getImport());
|
||||
importedFile.setCache(true);
|
||||
importedFile.setCacheHint(CacheHint.SCALE_AND_ROTATE);
|
||||
@@ -117,11 +156,7 @@ public class ModelFactory {
|
||||
}
|
||||
switch (tokenType) {
|
||||
case VELOCITY_PICKUP:
|
||||
case BUMPER_PICKUP:
|
||||
case RANDOM_PICKUP:
|
||||
case HANDLING_PICKUP:
|
||||
case WIND_WALKER_PICKUP:
|
||||
return makeTokenPickup(assets);
|
||||
return makeCoinPickup(assets);
|
||||
case FINISH_MARKER:
|
||||
case PLAIN_MARKER:
|
||||
case START_MARKER:
|
||||
@@ -150,22 +185,24 @@ public class ModelFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private static Model makeTokenPickup(Group assets) {
|
||||
Rotate animationRotate = new Rotate(0, new Point3D(0, 0, 1));
|
||||
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(
|
||||
animationRotate,
|
||||
new Translate(0, 0, -1)
|
||||
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 Rotate rotate = animationRotate;
|
||||
private Group group = assets;
|
||||
|
||||
@Override
|
||||
public void handle(long now) {
|
||||
rotation += 1;
|
||||
rotate.setAngle(rotation);
|
||||
((Rotate) group.getTransforms().get(1)).setAngle(rotation);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,10 +7,6 @@ package seng302.visualiser.fxObjects.assets_3D;
|
||||
public enum ModelType {
|
||||
|
||||
VELOCITY_PICKUP("velocity_pickup.dae"),
|
||||
HANDLING_PICKUP("turning_pickup.dae"),
|
||||
WIND_WALKER_PICKUP("wind_walker_pickup.dae"),
|
||||
BUMPER_PICKUP("bumper_pickup.dae"),
|
||||
RANDOM_PICKUP("random_pickup.dae"),
|
||||
FINISH_MARKER ("finish_marker.dae"),
|
||||
START_MARKER ("start_marker.dae"),
|
||||
PLAIN_MARKER ("plain_marker.dae"),
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
package seng302.visualiser;
|
||||
|
||||
import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.application.Application;
|
||||
import javafx.geometry.Point3D;
|
||||
import javafx.scene.Camera;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.PerspectiveCamera;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.SceneAntialiasing;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.PhongMaterial;
|
||||
import javafx.scene.shape.MeshView;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.scene.transform.Scale;
|
||||
import javafx.scene.transform.Translate;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* Created by cir27 on 7/09/17.
|
||||
*/
|
||||
public class test3d extends Application {
|
||||
|
||||
Group root = new Group();
|
||||
Scene scene;
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
// camera = new PerspectiveCamera();
|
||||
// gameObjects = new Group();
|
||||
// root3D = new Group(camera, gameObjects);
|
||||
scene = new Scene(
|
||||
root, 1000, 1000, true, SceneAntialiasing.BALANCED
|
||||
);
|
||||
gameView3DTest();
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
// scene.setCamera(camera);
|
||||
// primaryStage.setScene(scene);
|
||||
// primaryStage.show();
|
||||
//
|
||||
// StlMeshImporter importer = new StlMeshImporter();
|
||||
// importer.read(test3d.class.getResource("/meshes/dinghy_hull.stl").toString());
|
||||
// MeshView boat = new MeshView(importer.getImport());
|
||||
// boat.setMaterial(new PhongMaterial(Color.GREENYELLOW));
|
||||
//
|
||||
// importer = new StlMeshImporter();
|
||||
// importer.read(getClass().getResource("/meshes/dinghy_mast.stl").toString());
|
||||
// MeshView mast = new MeshView(importer.getImport());
|
||||
// mast.setMaterial(new PhongMaterial(Color.GREENYELLOW));
|
||||
//
|
||||
// importer = new StlMeshImporter();
|
||||
// importer.read(getClass().getResource("/meshes/dinghy_sail.stl").toString());
|
||||
// MeshView sail = new MeshView(importer.getImport());
|
||||
// sail.setMaterial(new PhongMaterial(Color.LIGHTGREY));
|
||||
//
|
||||
// gameObjects.getChildren().addAll(boat, mast, sail);
|
||||
//
|
||||
// gameObjects.getTransforms().add(new Scale(25, 25,25));
|
||||
// gameObjects.getTransforms().add(new Translate(15, 20,0));
|
||||
// gameObjects.getTransforms().addAll(
|
||||
// new Rotate(90, new Point3D(0,0,1)),
|
||||
// new Rotate(90, new Point3D(0, 1, 0))
|
||||
// );
|
||||
//
|
||||
//// PointLight light = new PointLight();
|
||||
//// light.setLightOn(true);
|
||||
//// light.getTransforms().add(new Translate(15, 20, 0));
|
||||
////
|
||||
//// PointLight light2 = new PointLight();
|
||||
//// light2.setLightOn(true);
|
||||
//// light2.getTransforms().add(new Translate(30, 40, 0));
|
||||
//
|
||||
//// root3D.getChildren().addAll(light);
|
||||
//
|
||||
// scene.setOnKeyPressed(event -> {
|
||||
// switch (event.getCode()) {
|
||||
// case UP:
|
||||
// gameObjects.getTransforms().add(new Rotate(5, new Point3D(0,0,1)));
|
||||
// break;
|
||||
// case DOWN:
|
||||
// gameObjects.getTransforms().add(new Rotate(-5, new Point3D(0,0,1)));
|
||||
// break;
|
||||
// case LEFT:
|
||||
// gameObjects.getTransforms().add(new Rotate(-5, new Point3D(0,1,0)));
|
||||
// break;
|
||||
// case RIGHT:
|
||||
// gameObjects.getTransforms().add(new Rotate(5, new Point3D(0,1,0)));
|
||||
// break;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// AnimationTimer animationTimer = new AnimationTimer() {
|
||||
// @Override
|
||||
// public void handle(long now) {
|
||||
// sail.getTransforms().add(new Rotate(0.5, 0, -1.36653, 0, new Point3D(0, 0, 1)));
|
||||
// }
|
||||
// };
|
||||
//
|
||||
//// animationTimer.start();
|
||||
}
|
||||
|
||||
private void gameView3DTest() {
|
||||
GameView3D gameView3D = new GameView3D();
|
||||
root.getChildren().add(gameView3D.getAssets());
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,11 @@
|
||||
-fx-border-color: -fx-decorator-color;
|
||||
-fx-border-width: 0 4 4 4;
|
||||
}
|
||||
|
||||
.jfx-decorator-button {
|
||||
-fx-focus-traversable: false; /* so decorator button will not be focused */
|
||||
}
|
||||
|
||||
/********* customised scroll bar for scroll pane ***********/
|
||||
|
||||
/* The main scrollbar **track** CSS class */
|
||||
@@ -100,3 +105,15 @@
|
||||
.slider .track {
|
||||
-fx-background-color: -fx-pp-dark-text-color;
|
||||
}
|
||||
|
||||
.jfx-snackbar-content {
|
||||
-fx-background-color: -fx-pp-front-color;
|
||||
-fx-padding: 0 5 0 5;
|
||||
-fx-spacing: 0 5 0 5;
|
||||
-fx-font-size: 15;
|
||||
}
|
||||
|
||||
.jfx-snackbar-toast {
|
||||
-fx-text-fill: -fx-pp-theme-color;
|
||||
-fx-font-size: 15;
|
||||
}
|
||||
@@ -48,6 +48,7 @@ GridPane .timer * {
|
||||
-fx-text-fill: -fx-pp-theme-color;
|
||||
-fx-font-size: 13px;
|
||||
-fx-pref-height: 35px;
|
||||
-fx-focus-traversable: false;
|
||||
}
|
||||
|
||||
#chatSend:hover {
|
||||
|
||||
@@ -38,30 +38,30 @@
|
||||
-fx-font-size: 23px;
|
||||
}
|
||||
|
||||
#connectButton, #roomConnectButton {
|
||||
#connectButton {
|
||||
-fx-background-color: -fx-pp-light-text-color; /* inverted */
|
||||
-fx-text-fill: -fx-pp-theme-color; /* inverted */
|
||||
-fx-font-size: 20px;
|
||||
-fx-pref-height: 45px;
|
||||
-fx-pref-height: 65px;
|
||||
}
|
||||
|
||||
#connectButton:hover, #roomConnectButton:hover {
|
||||
#connectButton:hover {
|
||||
-fx-font-size: 23px;
|
||||
}
|
||||
|
||||
#connectLabel, #connectLabel1, #serverPortNumber, #roomNumber, #serverHostName {
|
||||
#connectLabel, #serverPortNumber, #serverHostName {
|
||||
-fx-text-fill: -fx-pp-light-text-color;
|
||||
-fx-font-size: 18px;
|
||||
}
|
||||
|
||||
#serverHostName, #serverPortNumber, #roomNumber {
|
||||
#serverHostName, #serverPortNumber {
|
||||
-jfx-focus-color: -fx-pp-light-text-color;
|
||||
-jfx-unfocus-color: -fx-pp-light-text-color;
|
||||
-fx-prompt-text-fill: -fx-pp-light-text-color;
|
||||
}
|
||||
|
||||
|
||||
#serverHostName .error-label, #serverPortNumber .error-label, #roomNumber .error-label {
|
||||
#serverHostName .error-label, #serverPortNumber .error-label {
|
||||
-fx-font-size: 12px;
|
||||
-fx-text-fill: lightblue;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
-fx-font-size: 20px;
|
||||
-fx-text-fill: -fx-pp-light-text-color;
|
||||
-fx-background-color: -fx-pp-theme-color;
|
||||
-fx-focus-traversable: false;
|
||||
}
|
||||
|
||||
.jfx-rippler {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#keyBindingDialogHeader {
|
||||
-fx-font-size: 27px;
|
||||
-fx-text-fill: -fx-pp-dark-text-color;
|
||||
}
|
||||
|
||||
#closeLabel {
|
||||
-fx-font-size: 30;
|
||||
-fx-text-fill: -fx-pp-dark-text-color;
|
||||
}
|
||||
|
||||
#closeLabel:hover {
|
||||
-fx-text-fill: -fx-pp-theme-color;
|
||||
-fx-font-size: 33;
|
||||
}
|
||||
|
||||
JFXButton {
|
||||
-fx-background-color: -fx-pp-light-text-color;
|
||||
-fx-text-fill: -fx-pp-theme-color;
|
||||
-fx-font-size: 13px;
|
||||
}
|
||||
|
||||
Label {
|
||||
-fx-font-size: 15px;
|
||||
-fx-text-fill: -fx-pp-theme-color;
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
}
|
||||
|
||||
JFXToggleButton {
|
||||
-jfx-toggle-color: -fx-pp-theme-color;
|
||||
-fx-text-fill: -fx-pp-theme-color;
|
||||
}
|
||||
|
||||
#resetBtn {
|
||||
-fx-background-color: -fx-pp-theme-color;
|
||||
-fx-text-fill: -fx-pp-front-color;
|
||||
-fx-effect: -fx-pp-dropshadow-light;
|
||||
-fx-font-size: 18;
|
||||
}
|
||||
|
||||
#resetBtn:hover {
|
||||
-fx-font-size: 20;
|
||||
}
|
||||
|
||||
.jfx-snackbar-content {
|
||||
-fx-background-color: #323232;
|
||||
}
|
||||
|
||||
.jfx-snackbar-toast {
|
||||
-fx-text-fill: WHITE;
|
||||
}
|
||||
|
||||
.jfx-snackbar-action {
|
||||
-fx-text-fill: #ff4081;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* a separate file to dynamically change snackbar's color */
|
||||
.jfx-snackbar-toast {
|
||||
-fx-text-fill: red !important;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,147 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>Blender User</author>
|
||||
<authoring_tool>Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22</authoring_tool>
|
||||
</contributor>
|
||||
<created>2017-09-19T15:47:50</created>
|
||||
<modified>2017-09-19T15:47:50</modified>
|
||||
<unit name="meter" meter="1"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_images/>
|
||||
<library_effects>
|
||||
<effect id="Material_001_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0 0 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_002_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.64 6.87021e-4 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_materials>
|
||||
<material id="Material_001_001-material" name="Material_001_001">
|
||||
<instance_effect url="#Material_001_001-effect"/>
|
||||
</material>
|
||||
<material id="Material_002_001-material" name="Material_002_001">
|
||||
<instance_effect url="#Material_002_001-effect"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_geometries>
|
||||
<geometry id="Icosphere_001-mesh" name="Icosphere.001">
|
||||
<mesh>
|
||||
<source id="Icosphere_001-mesh-positions">
|
||||
<float_array id="Icosphere_001-mesh-positions-array" count="126">0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5257253 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8090167 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8090116 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-positions-array" count="42" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-normals">
|
||||
<float_array id="Icosphere_001-mesh-normals-array" count="240">0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-normals-array" count="80" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-map-0">
|
||||
<float_array id="Icosphere_001-mesh-map-0-array" count="480">0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-map-0-array" count="240" stride="2">
|
||||
<param name="S" type="float"/>
|
||||
<param name="T" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="Icosphere_001-mesh-vertices">
|
||||
<input semantic="POSITION" source="#Icosphere_001-mesh-positions"/>
|
||||
</vertices>
|
||||
<polylist material="Material_001_001-material" count="60">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 38 11 33 36 11 34 41 11 35 36 12 36 9 12 37 41 12 38 41 13 39 35 13 40 40 13 41 35 14 42 8 14 43 40 14 44 40 15 45 34 15 46 39 15 47 34 16 48 7 16 49 39 16 50 39 17 51 33 17 52 37 17 53 33 18 54 6 18 55 37 18 56 37 19 57 32 19 58 38 19 59 32 20 60 10 20 61 38 20 62 23 21 63 36 21 64 10 21 65 23 22 66 30 22 67 36 22 68 30 23 69 9 23 70 36 23 71 31 24 72 35 24 73 9 24 74 31 25 75 28 25 76 35 25 77 28 26 78 8 26 79 35 26 80 29 27 81 34 27 82 8 27 83 29 28 84 26 28 85 34 28 86 26 29 87 7 29 88 34 29 89 27 30 90 33 30 91 7 30 92 27 31 93 24 31 94 33 31 95 24 32 96 6 32 97 33 32 98 25 33 99 32 33 100 6 33 101 25 34 102 22 34 103 32 34 104 22 35 105 10 35 106 32 35 107 30 36 108 21 36 109 31 36 110 21 37 111 4 37 112 31 37 113 28 38 114 20 38 115 29 38 116 20 39 117 3 39 118 29 39 119 26 40 120 18 40 121 27 40 122 18 41 123 2 41 124 27 41 125 24 42 126 14 42 127 25 42 128 14 43 129 1 43 130 25 43 131 22 44 132 15 44 133 23 44 134 15 45 135 5 45 136 23 45 137 16 46 138 21 46 139 5 46 140 16 47 141 19 47 142 21 47 143 19 48 144 4 48 145 21 48 146 19 49 147 20 49 148 4 49 149 19 50 150 17 50 151 20 50 152 17 51 153 3 51 154 20 51 155 17 52 156 18 52 157 3 52 158 17 53 159 12 53 160 18 53 161 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 15 56 168 13 56 169 16 56 170 12 57 171 14 57 172 2 57 173 12 58 174 13 58 175 14 58 176 13 59 177 1 59 178 14 59 179</p>
|
||||
</polylist>
|
||||
<polylist material="Material_002_001-material" count="20">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239</p>
|
||||
</polylist>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_controllers/>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="Scene" name="Scene">
|
||||
<node id="Icosphere" name="Icosphere" type="NODE">
|
||||
<matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
|
||||
<instance_geometry url="#Icosphere_001-mesh" name="Icosphere">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="Material_001_001-material" target="#Material_001_001-material"/>
|
||||
<instance_material symbol="Material_002_001-material" target="#Material_002_001-material"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#Scene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,332 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>Blender User</author>
|
||||
<authoring_tool>Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22</authoring_tool>
|
||||
</contributor>
|
||||
<created>2017-09-19T15:54:38</created>
|
||||
<modified>2017-09-19T15:54:38</modified>
|
||||
<unit name="meter" meter="1"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_images/>
|
||||
<library_effects>
|
||||
<effect id="Material_001_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.8 0.6035923 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_002_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.8 0.1522076 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.01023849 0.004662884 0.64 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_002-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.64 0 0.2456551 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_003-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">8.07677e-5 0.64 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_004-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.64 0 0.005309466 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_005-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0 0 0 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_materials>
|
||||
<material id="Material_001_001-material" name="Material_001_001">
|
||||
<instance_effect url="#Material_001_001-effect"/>
|
||||
</material>
|
||||
<material id="Material_002_001-material" name="Material_002_001">
|
||||
<instance_effect url="#Material_002_001-effect"/>
|
||||
</material>
|
||||
<material id="Material_001-material" name="Material_001">
|
||||
<instance_effect url="#Material_001-effect"/>
|
||||
</material>
|
||||
<material id="Material_002-material" name="Material_002">
|
||||
<instance_effect url="#Material_002-effect"/>
|
||||
</material>
|
||||
<material id="Material_003-material" name="Material_003">
|
||||
<instance_effect url="#Material_003-effect"/>
|
||||
</material>
|
||||
<material id="Material_004-material" name="Material_004">
|
||||
<instance_effect url="#Material_004-effect"/>
|
||||
</material>
|
||||
<material id="Material_005-material" name="Material_005">
|
||||
<instance_effect url="#Material_005-effect"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_geometries>
|
||||
<geometry id="Icosphere_001-mesh" name="Icosphere.001">
|
||||
<mesh>
|
||||
<source id="Icosphere_001-mesh-positions">
|
||||
<float_array id="Icosphere_001-mesh-positions-array" count="126">0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5350354 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8183268 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8183217 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-positions-array" count="42" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-normals">
|
||||
<float_array id="Icosphere_001-mesh-normals-array" count="240">0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.570192 0.7464457 -0.3430743 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.6991799 0.2635454 0.6645987 0.05184978 0.746441 0.6634285 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.185151 0.569826 0.8006358 -0.4685443 0.5765037 0.6694099 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.009833872 0.9466192 0.3222044 -0.2904988 0.9398801 0.1795436 -0.5345759 0.7778646 0.3303867 -0.9071158 0.2635452 0.3281539 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7989099 0.5698285 -0.1924537 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.2925817 0.9466192 -0.1353079 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.8082743 0.5765079 0.1197141 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-normals-array" count="80" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-map-0">
|
||||
<float_array id="Icosphere_001-mesh-map-0-array" count="480">0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-map-0-array" count="240" stride="2">
|
||||
<param name="S" type="float"/>
|
||||
<param name="T" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="Icosphere_001-mesh-vertices">
|
||||
<input semantic="POSITION" source="#Icosphere_001-mesh-positions"/>
|
||||
</vertices>
|
||||
<polylist material="Material_001_001-material" count="15">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>36 12 36 9 12 37 41 12 38 35 14 42 8 14 43 40 14 44 34 16 48 7 16 49 39 16 50 33 18 54 6 18 55 37 18 56 32 20 60 10 20 61 38 20 62 30 23 69 9 23 70 36 23 71 28 26 78 8 26 79 35 26 80 26 29 87 7 29 88 34 29 89 24 32 96 6 32 97 33 32 98 22 35 105 10 35 106 32 35 107 16 47 141 19 47 142 21 47 143 19 50 150 17 50 151 20 50 152 17 53 159 12 53 160 18 53 161 15 56 168 13 56 169 16 56 170 12 58 174 13 58 175 14 58 176</p>
|
||||
</polylist>
|
||||
<polylist material="Material_002_001-material" count="20">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239</p>
|
||||
</polylist>
|
||||
<polylist material="Material_001-material" count="10">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>23 22 66 30 22 67 36 22 68 31 25 75 28 25 76 35 25 77 29 28 84 26 28 85 34 28 86 27 31 93 24 31 94 33 31 95 25 34 102 22 34 103 32 34 104 30 36 108 21 36 109 31 36 110 28 38 114 20 38 115 29 38 116 26 40 120 18 40 121 27 40 122 24 42 126 14 42 127 25 42 128 22 44 132 15 44 133 23 44 134</p>
|
||||
</polylist>
|
||||
<polylist material="Material_002-material" count="10">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 23 21 63 36 21 64 10 21 65 31 24 72 35 24 73 9 24 74 29 27 81 34 27 82 8 27 83 27 30 90 33 30 91 7 30 92 25 33 99 32 33 100 6 33 101</p>
|
||||
</polylist>
|
||||
<polylist material="Material_003-material" count="5">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 </vcount>
|
||||
<p>38 11 33 36 11 34 41 11 35 41 13 39 35 13 40 40 13 41 40 15 45 34 15 46 39 15 47 39 17 51 33 17 52 37 17 53 37 19 57 32 19 58 38 19 59</p>
|
||||
</polylist>
|
||||
<polylist material="Material_004-material" count="10">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 16 46 138 21 46 139 5 46 140 19 49 147 20 49 148 4 49 149 17 52 156 18 52 157 3 52 158 12 57 171 14 57 172 2 57 173</p>
|
||||
</polylist>
|
||||
<polylist material="Material_005-material" count="10">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>21 37 111 4 37 112 31 37 113 20 39 117 3 39 118 29 39 119 18 41 123 2 41 124 27 41 125 14 43 129 1 43 130 25 43 131 15 45 135 5 45 136 23 45 137 19 48 144 4 48 145 21 48 146 17 51 153 3 51 154 20 51 155 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 13 59 177 1 59 178 14 59 179</p>
|
||||
</polylist>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_controllers/>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="Scene" name="Scene">
|
||||
<node id="Icosphere" name="Icosphere" type="NODE">
|
||||
<matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
|
||||
<instance_geometry url="#Icosphere_001-mesh" name="Icosphere">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="Material_001_001-material" target="#Material_001_001-material"/>
|
||||
<instance_material symbol="Material_002_001-material" target="#Material_002_001-material"/>
|
||||
<instance_material symbol="Material_001-material" target="#Material_001-material"/>
|
||||
<instance_material symbol="Material_002-material" target="#Material_002-material"/>
|
||||
<instance_material symbol="Material_003-material" target="#Material_003-material"/>
|
||||
<instance_material symbol="Material_004-material" target="#Material_004-material"/>
|
||||
<instance_material symbol="Material_005-material" target="#Material_005-material"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#Scene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
@@ -1,147 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>Blender User</author>
|
||||
<authoring_tool>Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22</authoring_tool>
|
||||
</contributor>
|
||||
<created>2017-09-19T15:45:46</created>
|
||||
<modified>2017-09-19T15:45:46</modified>
|
||||
<unit name="meter" meter="1"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_images/>
|
||||
<library_effects>
|
||||
<effect id="Material_001_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.004555753 0.0885511 0.003947978 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_002_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.64 0.1458963 0.001825521 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_materials>
|
||||
<material id="Material_001_001-material" name="Material_001_001">
|
||||
<instance_effect url="#Material_001_001-effect"/>
|
||||
</material>
|
||||
<material id="Material_002_001-material" name="Material_002_001">
|
||||
<instance_effect url="#Material_002_001-effect"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_geometries>
|
||||
<geometry id="Icosphere_001-mesh" name="Icosphere.001">
|
||||
<mesh>
|
||||
<source id="Icosphere_001-mesh-positions">
|
||||
<float_array id="Icosphere_001-mesh-positions-array" count="126">0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5257253 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8090167 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8090116 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-positions-array" count="42" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-normals">
|
||||
<float_array id="Icosphere_001-mesh-normals-array" count="240">0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-normals-array" count="80" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-map-0">
|
||||
<float_array id="Icosphere_001-mesh-map-0-array" count="480">0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-map-0-array" count="240" stride="2">
|
||||
<param name="S" type="float"/>
|
||||
<param name="T" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="Icosphere_001-mesh-vertices">
|
||||
<input semantic="POSITION" source="#Icosphere_001-mesh-positions"/>
|
||||
</vertices>
|
||||
<polylist material="Material_001_001-material" count="60">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 38 11 33 36 11 34 41 11 35 36 12 36 9 12 37 41 12 38 41 13 39 35 13 40 40 13 41 35 14 42 8 14 43 40 14 44 40 15 45 34 15 46 39 15 47 34 16 48 7 16 49 39 16 50 39 17 51 33 17 52 37 17 53 33 18 54 6 18 55 37 18 56 37 19 57 32 19 58 38 19 59 32 20 60 10 20 61 38 20 62 23 21 63 36 21 64 10 21 65 23 22 66 30 22 67 36 22 68 30 23 69 9 23 70 36 23 71 31 24 72 35 24 73 9 24 74 31 25 75 28 25 76 35 25 77 28 26 78 8 26 79 35 26 80 29 27 81 34 27 82 8 27 83 29 28 84 26 28 85 34 28 86 26 29 87 7 29 88 34 29 89 27 30 90 33 30 91 7 30 92 27 31 93 24 31 94 33 31 95 24 32 96 6 32 97 33 32 98 25 33 99 32 33 100 6 33 101 25 34 102 22 34 103 32 34 104 22 35 105 10 35 106 32 35 107 30 36 108 21 36 109 31 36 110 21 37 111 4 37 112 31 37 113 28 38 114 20 38 115 29 38 116 20 39 117 3 39 118 29 39 119 26 40 120 18 40 121 27 40 122 18 41 123 2 41 124 27 41 125 24 42 126 14 42 127 25 42 128 14 43 129 1 43 130 25 43 131 22 44 132 15 44 133 23 44 134 15 45 135 5 45 136 23 45 137 16 46 138 21 46 139 5 46 140 16 47 141 19 47 142 21 47 143 19 48 144 4 48 145 21 48 146 19 49 147 20 49 148 4 49 149 19 50 150 17 50 151 20 50 152 17 51 153 3 51 154 20 51 155 17 52 156 18 52 157 3 52 158 17 53 159 12 53 160 18 53 161 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 15 56 168 13 56 169 16 56 170 12 57 171 14 57 172 2 57 173 12 58 174 13 58 175 14 58 176 13 59 177 1 59 178 14 59 179</p>
|
||||
</polylist>
|
||||
<polylist material="Material_002_001-material" count="20">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239</p>
|
||||
</polylist>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_controllers/>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="Scene" name="Scene">
|
||||
<node id="Icosphere" name="Icosphere" type="NODE">
|
||||
<matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
|
||||
<instance_geometry url="#Icosphere_001-mesh" name="Icosphere">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="Material_001_001-material" target="#Material_001_001-material"/>
|
||||
<instance_material symbol="Material_002_001-material" target="#Material_002_001-material"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#Scene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
@@ -1,147 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>Blender User</author>
|
||||
<authoring_tool>Blender 2.78.0 commit date:2016-09-26, commit time:12:42, hash:4bb1e22</authoring_tool>
|
||||
</contributor>
|
||||
<created>2017-09-19T15:46:34</created>
|
||||
<modified>2017-09-19T15:46:34</modified>
|
||||
<unit name="meter" meter="1"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_images/>
|
||||
<library_effects>
|
||||
<effect id="Material_001_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.03920602 0.04758029 0.8 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
<effect id="Material_002_001-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.64 0.5287738 0.5454956 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.25 0.25 0.25 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_materials>
|
||||
<material id="Material_001_001-material" name="Material_001_001">
|
||||
<instance_effect url="#Material_001_001-effect"/>
|
||||
</material>
|
||||
<material id="Material_002_001-material" name="Material_002_001">
|
||||
<instance_effect url="#Material_002_001-effect"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_geometries>
|
||||
<geometry id="Icosphere_001-mesh" name="Icosphere.001">
|
||||
<mesh>
|
||||
<source id="Icosphere_001-mesh-positions">
|
||||
<float_array id="Icosphere_001-mesh-positions-array" count="126">0 0 -1 0.7236073 -0.5257253 -0.4472195 -0.276388 -0.8506492 -0.4472199 -0.8944262 0 -0.4472156 -0.276388 0.8506492 -0.4472199 0.7236073 0.5257253 -0.4472195 0.276388 -0.8506492 0.4472199 -0.7236073 -0.5257253 0.4472195 -0.7236073 0.5257253 0.4472195 0.276388 0.8506492 0.4472199 0.8944262 0 0.4472156 0 0 1 -0.1624554 -0.4999952 -0.8506544 0.4253227 -0.3090114 -0.8506542 0.2628688 -0.8090116 -0.5257377 0.8506479 0 -0.5257359 0.4253227 0.3090114 -0.8506542 -0.5257298 0 -0.8506517 -0.6881894 -0.4999969 -0.5257362 -0.1624554 0.4999952 -0.8506544 -0.6881894 0.4999969 -0.5257362 0.2628688 0.8090116 -0.5257377 0.9510579 -0.3090126 0 0.9510579 0.3090126 0 0 -1 0 0.5877856 -0.8090167 0 -0.9510579 -0.3090126 0 -0.5877856 -0.8090167 0 -0.5877856 0.8090167 0 -0.9510579 0.3090126 0 0.5877856 0.8090167 0 0 1 0 0.6881894 -0.4999969 0.5257362 -0.2628688 -0.8090116 0.5257377 -0.8506479 0 0.5257359 -0.2628688 0.8090116 0.5257377 0.6881894 0.4999969 0.5257362 0.1624554 -0.4999952 0.8506544 0.5257298 0 0.8506517 -0.4253227 -0.3090114 0.8506542 -0.4253227 0.3090114 0.8506542 0.1624554 0.4999952 0.8506544</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-positions-array" count="42" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-normals">
|
||||
<float_array id="Icosphere_001-mesh-normals-array" count="240">0.7002241 -0.2680317 -0.6616988 0.9049891 -0.2680316 -0.3303847 0.02474653 -0.9435215 -0.330386 -0.8896973 -0.3150947 -0.3303849 -0.5746018 0.7487837 -0.3303875 0.5345759 0.7778646 -0.3303867 0.4089462 -0.6284253 0.6616985 -0.4712997 -0.5831224 0.6616985 -0.7002241 0.2680317 0.6616988 0.03853034 0.7487788 0.6616991 0.7240421 0.1947362 0.6616954 0.4911195 0.356821 0.7946575 0.4089463 0.6284252 0.6616985 -0.1875942 0.5773453 0.7946577 -0.4712997 0.5831224 0.6616985 -0.6070605 0 0.7946557 -0.7002241 -0.2680318 0.6616988 -0.1875942 -0.5773453 0.7946577 0.03853034 -0.7487788 0.6616991 0.4911194 -0.356821 0.7946576 0.7240421 -0.1947363 0.6616954 0.8896973 0.3150946 0.3303849 0.7946556 0.5773479 0.1875951 0.5746018 0.7487836 0.3303875 -0.02474653 0.9435214 0.3303861 -0.3035309 0.9341714 0.1875976 -0.5345759 0.7778646 0.3303867 -0.9049891 0.2680316 0.3303846 -0.9822458 0 0.1875985 -0.9049891 -0.2680316 0.3303846 -0.5345759 -0.7778646 0.3303867 -0.3035309 -0.9341714 0.1875975 -0.02474653 -0.9435214 0.3303861 0.5746018 -0.7487836 0.3303875 0.7946556 -0.5773479 0.1875951 0.8896973 -0.3150946 0.3303849 0.3035309 0.9341714 -0.1875975 0.02474653 0.9435215 -0.330386 -0.7946556 0.5773479 -0.1875951 -0.8896973 0.3150945 -0.3303849 -0.7946556 -0.5773479 -0.1875951 -0.5746018 -0.7487836 -0.3303875 0.3035309 -0.9341714 -0.1875976 0.5345759 -0.7778645 -0.3303867 0.9822458 0 -0.1875985 0.9049891 0.2680316 -0.3303847 0.4712997 0.5831224 -0.6616986 0.1875942 0.5773453 -0.7946577 -0.0385304 0.7487788 -0.6616991 -0.4089462 0.6284252 -0.6616984 -0.4911194 0.356821 -0.7946576 -0.7240421 0.1947362 -0.6616954 -0.7240421 -0.1947362 -0.6616954 -0.4911195 -0.356821 -0.7946575 -0.4089462 -0.6284252 -0.6616984 0.7002241 0.2680318 -0.6616988 0.6070605 0 -0.7946556 -0.0385304 -0.7487788 -0.6616991 0.1875942 -0.5773453 -0.7946577 0.4712997 -0.5831224 -0.6616986 0.1023808 -0.3150898 -0.9435235 -0.2680341 -0.1947365 -0.9435229 -0.2680341 0.1947365 -0.9435229 0.1023808 0.3150898 -0.9435235 0.802609 -0.5831265 -0.1256273 -0.306569 -0.9435216 -0.1256289 -0.9920774 0 -0.1256284 -0.306569 0.9435216 -0.1256289 0.802609 0.5831265 -0.1256273 0.2680341 0.1947365 0.9435229 -0.1023808 0.3150899 0.9435235 -0.3313045 0 0.943524 -0.1023808 -0.3150898 0.9435235 0.2680341 -0.1947365 0.9435229 0.306569 0.9435216 0.1256289 -0.802609 0.5831265 0.1256274 -0.802609 -0.5831265 0.1256274 0.306569 -0.9435216 0.1256289 0.9920774 0 0.1256284 0.3313045 0 -0.943524</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-normals-array" count="80" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Icosphere_001-mesh-map-0">
|
||||
<float_array id="Icosphere_001-mesh-map-0-array" count="480">0.1891562 0.4353454 0.2201194 0.3408505 0.2923961 0.4111046 0.1891562 0.4353454 0.2923961 0.4111046 0.2610388 0.5272238 0.06585121 0.2636542 0.1202549 0.3546833 1.02655e-4 0.3599037 0.1891674 0.09197556 0.120263 0.1726311 0.07693755 0.06042814 0.3900915 0.1577098 0.2924051 0.1162222 0.3863589 0.0410583 0.3900838 0.3696232 0.3989981 0.2636671 0.4998953 0.3296785 0.6099237 0.1577003 0.7076132 0.1162198 0.6911104 0.216345 0.6099155 0.3696137 0.6010091 0.2636568 0.6911069 0.3109756 0.8108381 0.4353509 0.7076001 0.4111025 0.779882 0.3408538 0.934156 0.263669 0.8797454 0.354694 0.833759 0.263666 0.8108526 0.09198099 0.8797511 0.1726418 0.7798885 0.1864736 0.7798885 0.1864736 0.8797511 0.1726418 0.833759 0.263666 0.8797511 0.1726418 0.934156 0.263669 0.833759 0.263666 0.833759 0.263666 0.8797454 0.354694 0.779882 0.3408538 0.8797454 0.354694 0.8108381 0.4353509 0.779882 0.3408538 0.779882 0.3408538 0.7076001 0.4111025 0.6911069 0.3109756 0.7076001 0.4111025 0.6099155 0.3696137 0.6911069 0.3109756 0.6911069 0.3109756 0.6010091 0.2636568 0.6911104 0.216345 0.6010091 0.2636568 0.6099237 0.1577003 0.6911104 0.216345 0.6911104 0.216345 0.7076132 0.1162198 0.7798885 0.1864736 0.7076132 0.1162198 0.8108526 0.09198099 0.7798885 0.1864736 0.923085 0.06044203 0.8797511 0.1726418 0.8108526 0.09198099 0.923085 0.06044203 0.9998974 0.16742 0.8797511 0.1726418 0.9998974 0.16742 0.934156 0.263669 0.8797511 0.1726418 0.9998974 0.3599234 0.8797454 0.354694 0.934156 0.263669 0.9998974 0.3599234 0.923074 0.4668999 0.8797454 0.354694 0.923074 0.4668999 0.8108381 0.4353509 0.8797454 0.354694 0.7389487 0.527224 0.7076001 0.4111025 0.8108381 0.4353509 0.7389487 0.527224 0.6136447 0.4862654 0.7076001 0.4111025 0.6136447 0.4862654 0.6099155 0.3696137 0.7076001 0.4111025 0.5001069 0.3296607 0.6010091 0.2636568 0.6099155 0.3696137 0.5001069 0.3296607 0.5001106 0.1976431 0.6010091 0.2636568 0.5001106 0.1976431 0.6099237 0.1577003 0.6010091 0.2636568 0.613665 0.041049 0.7076132 0.1162198 0.6099237 0.1577003 0.613665 0.041049 0.7389741 1.02655e-4 0.7076132 0.1162198 0.7389741 1.02655e-4 0.8108526 0.09198099 0.7076132 0.1162198 0.4998953 0.3296785 0.3989981 0.2636671 0.4999017 0.1976609 0.3989981 0.2636671 0.3900915 0.1577098 0.4999017 0.1976609 0.3863589 0.0410583 0.2924051 0.1162222 0.2610529 1.02655e-4 0.2924051 0.1162222 0.1891674 0.09197556 0.2610529 1.02655e-4 0.07693755 0.06042814 0.120263 0.1726311 1.17172e-4 0.1674003 0.120263 0.1726311 0.06585121 0.2636542 1.17172e-4 0.1674003 1.02655e-4 0.3599037 0.1202549 0.3546833 0.07691794 0.466886 0.1202549 0.3546833 0.1891562 0.4353454 0.07691794 0.466886 0.2610388 0.5272238 0.2923961 0.4111046 0.3863458 0.4862747 0.2923961 0.4111046 0.3900838 0.3696232 0.3863458 0.4862747 0.3088967 0.3109791 0.3989981 0.2636671 0.3900838 0.3696232 0.3088967 0.3109791 0.3089004 0.2163485 0.3989981 0.2636671 0.3089004 0.2163485 0.3900915 0.1577098 0.3989981 0.2636671 0.3089004 0.2163485 0.2924051 0.1162222 0.3900915 0.1577098 0.3089004 0.2163485 0.2201245 0.1864705 0.2924051 0.1162222 0.2201245 0.1864705 0.1891674 0.09197556 0.2924051 0.1162222 0.2201245 0.1864705 0.120263 0.1726311 0.1891674 0.09197556 0.2201245 0.1864705 0.1662483 0.2636588 0.120263 0.1726311 0.1662483 0.2636588 0.06585121 0.2636542 0.120263 0.1726311 0.2923961 0.4111046 0.3088967 0.3109791 0.3900838 0.3696232 0.2923961 0.4111046 0.2201194 0.3408505 0.3088967 0.3109791 0.1662483 0.2636588 0.1202549 0.3546833 0.06585121 0.2636542 0.1662483 0.2636588 0.2201194 0.3408505 0.1202549 0.3546833 0.2201194 0.3408505 0.1891562 0.4353454 0.1202549 0.3546833 0.2038319 0.6020938 0.07803589 0.775239 2.88122e-4 0.5359594 0.2038319 0.6020938 2.88122e-4 0.5359594 0.2038319 0.3880734 0.2038319 0.6020938 0.2038319 0.3880734 0.4073758 0.5359594 0.2038319 0.6020938 0.4073758 0.5359594 0.329628 0.775239 0.8690316 0.364753 0.791095 0.5663278 0.6529134 0.364753 0.5301482 0.1791203 0.6523408 0.3573763 0.407952 0.3573763 0.5301446 0.5663277 0.407952 0.3880734 0.6523372 0.3880734 0.20244 0.9919336 0.20244 0.7758153 0.4040137 0.9139961 0.4079523 0.566904 0.6095281 0.6448412 0.407952 0.7830209 0.203883 2.88122e-4 0.4073758 0.1482443 0.2038091 0.2143085 0.4073758 0.1482443 0.3295453 0.3874972 0.2038091 0.2143085 0.3295453 0.3874972 0.07795333 0.3874103 0.2038091 0.2143085 0.07795333 0.3874103 2.88122e-4 0.1481037 0.2038091 0.2143085 2.88122e-4 0.1481037 0.203883 2.88122e-4 0.2038091 0.2143085 0.6523409 0.178544 0.407952 0.1785441 0.5301446 2.88122e-4 0.7910969 0.2018641 0.6529171 2.88122e-4 0.8690339 2.88122e-4 0.8116793 0.6448401 0.6101047 0.7830221 0.6101044 0.566904 2.88169e-4 0.7758153 0.2018638 0.9139932 2.88122e-4 0.9919315 0.407952 0.7835971 0.6095241 0.9217739 0.407952 0.999712 0.07803589 0.775239 0.2038319 0.6020938 0.329628 0.775239</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Icosphere_001-mesh-map-0-array" count="240" stride="2">
|
||||
<param name="S" type="float"/>
|
||||
<param name="T" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="Icosphere_001-mesh-vertices">
|
||||
<input semantic="POSITION" source="#Icosphere_001-mesh-positions"/>
|
||||
</vertices>
|
||||
<polylist material="Material_001_001-material" count="60">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>1 0 0 13 0 1 15 0 2 1 1 3 15 1 4 22 1 5 2 2 6 14 2 7 24 2 8 3 3 9 18 3 10 26 3 11 4 4 12 20 4 13 28 4 14 5 5 15 21 5 16 30 5 17 6 6 18 32 6 19 37 6 20 7 7 21 33 7 22 39 7 23 8 8 24 34 8 25 40 8 26 9 9 27 35 9 28 41 9 29 10 10 30 36 10 31 38 10 32 38 11 33 36 11 34 41 11 35 36 12 36 9 12 37 41 12 38 41 13 39 35 13 40 40 13 41 35 14 42 8 14 43 40 14 44 40 15 45 34 15 46 39 15 47 34 16 48 7 16 49 39 16 50 39 17 51 33 17 52 37 17 53 33 18 54 6 18 55 37 18 56 37 19 57 32 19 58 38 19 59 32 20 60 10 20 61 38 20 62 23 21 63 36 21 64 10 21 65 23 22 66 30 22 67 36 22 68 30 23 69 9 23 70 36 23 71 31 24 72 35 24 73 9 24 74 31 25 75 28 25 76 35 25 77 28 26 78 8 26 79 35 26 80 29 27 81 34 27 82 8 27 83 29 28 84 26 28 85 34 28 86 26 29 87 7 29 88 34 29 89 27 30 90 33 30 91 7 30 92 27 31 93 24 31 94 33 31 95 24 32 96 6 32 97 33 32 98 25 33 99 32 33 100 6 33 101 25 34 102 22 34 103 32 34 104 22 35 105 10 35 106 32 35 107 30 36 108 21 36 109 31 36 110 21 37 111 4 37 112 31 37 113 28 38 114 20 38 115 29 38 116 20 39 117 3 39 118 29 39 119 26 40 120 18 40 121 27 40 122 18 41 123 2 41 124 27 41 125 24 42 126 14 42 127 25 42 128 14 43 129 1 43 130 25 43 131 22 44 132 15 44 133 23 44 134 15 45 135 5 45 136 23 45 137 16 46 138 21 46 139 5 46 140 16 47 141 19 47 142 21 47 143 19 48 144 4 48 145 21 48 146 19 49 147 20 49 148 4 49 149 19 50 150 17 50 151 20 50 152 17 51 153 3 51 154 20 51 155 17 52 156 18 52 157 3 52 158 17 53 159 12 53 160 18 53 161 12 54 162 2 54 163 18 54 164 15 55 165 16 55 166 5 55 167 15 56 168 13 56 169 16 56 170 12 57 171 14 57 172 2 57 173 12 58 174 13 58 175 14 58 176 13 59 177 1 59 178 14 59 179</p>
|
||||
</polylist>
|
||||
<polylist material="Material_002_001-material" count="20">
|
||||
<input semantic="VERTEX" source="#Icosphere_001-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Icosphere_001-mesh-normals" offset="1"/>
|
||||
<input semantic="TEXCOORD" source="#Icosphere_001-mesh-map-0" offset="2" set="0"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>0 60 180 13 60 181 12 60 182 0 61 183 12 61 184 17 61 185 0 62 186 17 62 187 19 62 188 0 63 189 19 63 190 16 63 191 1 64 192 22 64 193 25 64 194 2 65 195 24 65 196 27 65 197 3 66 198 26 66 199 29 66 200 4 67 201 28 67 202 31 67 203 5 68 204 30 68 205 23 68 206 38 69 207 41 69 208 11 69 209 41 70 210 40 70 211 11 70 212 40 71 213 39 71 214 11 71 215 39 72 216 37 72 217 11 72 218 37 73 219 38 73 220 11 73 221 30 74 222 31 74 223 9 74 224 28 75 225 29 75 226 8 75 227 26 76 228 27 76 229 7 76 230 24 77 231 25 77 232 6 77 233 22 78 234 23 78 235 10 78 236 13 79 237 0 79 238 16 79 239</p>
|
||||
</polylist>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_controllers/>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="Scene" name="Scene">
|
||||
<node id="Icosphere" name="Icosphere" type="NODE">
|
||||
<matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
|
||||
<instance_geometry url="#Icosphere_001-mesh" name="Icosphere">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="Material_001_001-material" target="#Material_001_001-material"/>
|
||||
<instance_material symbol="Material_002_001-material" target="#Material_002_001-material"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#Scene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
@@ -12,7 +12,7 @@
|
||||
</BoatShapes>
|
||||
<Boats>
|
||||
<#list boats as boat>
|
||||
<Boat Type="Yacht" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullID}" StoweName="${boat.shortName}" ShortName="${boat.shortName}"
|
||||
<Boat Type="${boat.boatType}" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullID}" StoweName="${boat.shortName}" ShortName="${boat.shortName}"
|
||||
BoatName="${boat.boatName}" Country="${boat.country}" Color="${boat.boatColor}">
|
||||
<GPSposition Z="0" Y="3.7" X="0" />
|
||||
<MastTop Z="0" Y="6.2" X="0" />
|
||||
|
||||
@@ -52,19 +52,10 @@
|
||||
<Insets left="35.0" top="-15.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="roomLabel" text="Room: 2145" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<font>
|
||||
<Font size="31.0" />
|
||||
</font>
|
||||
<GridPane.margin>
|
||||
<Insets right="20.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
</children>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="732.0" minWidth="10.0" prefWidth="507.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="10000.0" minWidth="10.0" prefWidth="155.0" />
|
||||
<ColumnConstraints halignment="RIGHT" hgrow="NEVER" maxWidth="445.0" minWidth="10.0" prefWidth="238.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="50.0" prefHeight="74.0" vgrow="SOMETIMES" />
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.*?>
|
||||
<?import javafx.scene.shape.*?>
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import java.lang.String?>
|
||||
@@ -23,14 +14,12 @@
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<AnchorPane fx:id="rvAnchorPane" maxHeight="1.7976931348623157E308"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="800.0"
|
||||
prefWidth="1200.0" style="-fx-background-color: lightblue;" xmlns="http://javafx.com/javafx/8"
|
||||
<StackPane fx:id="contentStackPane" maxHeight="1.7976931348623157E308"
|
||||
maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity"
|
||||
prefHeight="800.0" prefWidth="1200.0"
|
||||
style="-fx-background-color: skyblue;" xmlns="http://javafx.com/javafx/8"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="seng302.visualiser.controllers.RaceViewController">
|
||||
<children>
|
||||
<StackPane fx:id="contentAnchorPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="800.0" prefWidth="1200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<GridPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
|
||||
prefHeight="800.0" prefWidth="1200.0">
|
||||
@@ -171,7 +160,8 @@
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="110.0"
|
||||
minWidth="110.0" prefWidth="110.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0" minWidth="10.0"
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="132.0"
|
||||
minWidth="10.0"
|
||||
prefWidth="132.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
@@ -245,64 +235,11 @@
|
||||
<Insets bottom="10.0" left="10.0" top="40.0"/>
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
|
||||
prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="velocityIcon" fitHeight="123.0" fitWidth="139.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/velocity.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="handlingIcon" fitHeight="123.0" fitWidth="139.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/handlingIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="windWalkerIcon" fitHeight="123.0" fitWidth="139.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="2" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/windWalkerIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
<ImageView fx:id="bumperIcon" fitHeight="123.0" fitWidth="139.0"
|
||||
pickOnBounds="true" preserveRatio="true" visible="false"
|
||||
GridPane.columnIndex="3" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="1">
|
||||
<image>
|
||||
<Image url="@../icons/bumperIcon.png"/>
|
||||
</image>
|
||||
</ImageView>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</StackPane>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<String fx:value="/css/Master.css"/>
|
||||
<String fx:value="/css/RaceView.css"/>
|
||||
</stylesheets>
|
||||
</AnchorPane>
|
||||
</StackPane>
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import java.lang.String?>
|
||||
@@ -18,48 +12,35 @@
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<StackPane fx:id="serverListMainStackPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.ServerListController">
|
||||
<children>
|
||||
<GridPane fx:id="serverListMainGridPane" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
|
||||
<children>
|
||||
<GridPane fx:id="connectGridPane" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<JFXButton fx:id="connectButton" buttonType="RAISED" prefHeight="45.0" prefWidth="220.0" ripplerFill="#3493e3" text="CONNECT" textFill="WHITE" GridPane.columnIndex="5" GridPane.halignment="RIGHT" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<JFXButton fx:id="connectButton" buttonType="RAISED" prefHeight="45.0"
|
||||
prefWidth="220.0" ripplerFill="#3493e3" text="CONNECT" textFill="WHITE"
|
||||
GridPane.columnIndex="5" GridPane.halignment="RIGHT"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="50.0" />
|
||||
</GridPane.margin>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="serverHostName" maxHeight="30.0" minHeight="30.0" prefHeight="30.0" promptText="Host Name" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<JFXTextField fx:id="serverHostName" maxHeight="30.0" minHeight="30.0" prefHeight="30.0" promptText="Host Name" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets left="20.0" right="20.0" />
|
||||
</GridPane.margin>
|
||||
</JFXTextField>
|
||||
<JFXTextField fx:id="serverPortNumber" maxHeight="30.0" minHeight="30.0" prefHeight="30.0" promptText="Port Number" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<JFXTextField fx:id="serverPortNumber" maxHeight="30.0" minHeight="30.0" prefHeight="30.0" promptText="Port Number" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets left="20.0" right="20.0" />
|
||||
</GridPane.margin>
|
||||
</JFXTextField>
|
||||
<Label fx:id="connectLabel" text="Direct Connect:" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<Label fx:id="connectLabel" text="Direct Connect:" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="45.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Label fx:id="connectLabel1" text="Connect to Room:" GridPane.columnIndex="2" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="45.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<JFXButton fx:id="roomConnectButton" buttonType="RAISED" prefHeight="45.0" prefWidth="220.0" text="CONNECT" GridPane.columnIndex="5" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="50.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="roomNumber" maxHeight="30.0" minHeight="30.0" prefHeight="30.0" promptText="Room Number" GridPane.columnIndex="3" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets left="20.0" right="20.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
</JFXTextField>
|
||||
</children>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" />
|
||||
@@ -70,7 +51,6 @@
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="273.0" minWidth="250.0" prefWidth="273.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
@@ -96,7 +76,10 @@
|
||||
<Insets left="35.0" top="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<JFXButton id="hostButton" fx:id="serverListHostButton" buttonType="RAISED" prefHeight="45.0" prefWidth="220.0" text="HOST" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<JFXButton id="hostButton" fx:id="serverListHostButton" buttonType="RAISED"
|
||||
prefHeight="45.0" prefWidth="220.0"
|
||||
text="HOST" GridPane.columnIndex="1" GridPane.halignment="RIGHT"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="50.0"/>
|
||||
</GridPane.margin>
|
||||
@@ -116,8 +99,8 @@
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="400.0" prefHeight="465.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="400.0" prefHeight="400.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<stylesheets>
|
||||
<String fx:value="/css/Master.css"/>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import com.jfoenix.controls.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXColorPicker?>
|
||||
<?import com.jfoenix.controls.JFXDialogLayout?>
|
||||
@@ -10,52 +16,43 @@
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<JFXDialogLayout maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
|
||||
minWidth="-Infinity" prefWidth="400.0" xmlns="http://javafx.com/javafx/8"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="seng302.visualiser.controllers.dialogs.BoatCustomizeController">
|
||||
|
||||
<JFXDialogLayout maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="400.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.visualiser.controllers.dialogs.BoatCustomizeController">
|
||||
<children>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="90.0" minHeight="90.0" prefHeight="90.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="100.0" minHeight="100.0" prefHeight="100.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="125.0" minHeight="61.0" prefHeight="99.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="164.0" minHeight="100.0" prefHeight="126.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="90.0" minHeight="48.0" prefHeight="48.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="207.0" minHeight="93.0" prefHeight="181.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="207.0" minHeight="93.0" prefHeight="181.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="145.0" minHeight="66.0" prefHeight="109.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="125.0" minHeight="24.0" prefHeight="72.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="164.0" minHeight="100.0" prefHeight="105.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="hostDialogHeader" text="Customize Boat" GridPane.halignment="CENTER"
|
||||
GridPane.valignment="CENTER"/>
|
||||
<JFXButton fx:id="submitBtn" prefHeight="45.0" prefWidth="220.0" text="Customize Boat" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="CENTER" />
|
||||
<JFXTextField fx:id="boatName" focusColor="#6c6c6c" promptText="Boat Name"
|
||||
unFocusColor="#6b6b6b" GridPane.rowIndex="1">
|
||||
<Label fx:id="hostDialogHeader" text="Customize Boat" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
|
||||
<JFXButton fx:id="submitBtn" prefHeight="45.0" prefWidth="220.0" text="Customize Boat" GridPane.halignment="CENTER" GridPane.rowIndex="5" GridPane.valignment="CENTER" />
|
||||
<JFXTextField fx:id="boatName" focusColor="#6c6c6c" promptText="Boat Name" unFocusColor="#6b6b6b" GridPane.rowIndex="3">
|
||||
<GridPane.margin>
|
||||
<Insets left="30.0" right="30.0" />
|
||||
</GridPane.margin></JFXTextField>
|
||||
<GridPane GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane GridPane.halignment="CENTER" GridPane.rowIndex="4" GridPane.valignment="CENTER">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="139.0" minWidth="10.0"
|
||||
prefWidth="94.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="203.0" minWidth="10.0"
|
||||
prefWidth="198.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="139.0" minWidth="10.0" prefWidth="94.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="203.0" minWidth="10.0" prefWidth="198.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints percentHeight="100.0" valignment="CENTER" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="boatColorLabel" prefHeight="25.0" prefWidth="96.0"
|
||||
text="Boat Color" GridPane.valignment="CENTER">
|
||||
<Label fx:id="boatColorLabel" prefHeight="25.0" prefWidth="96.0" text="Boat Color" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets top="-10.0" />
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<JFXColorPicker fx:id="colorPicker" onAction="#colorChanged"
|
||||
GridPane.columnIndex="1" GridPane.valignment="CENTER">
|
||||
<JFXColorPicker fx:id="colorPicker" onAction="#colorChanged" GridPane.columnIndex="1" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets left="30.0" top="-10.0" />
|
||||
</GridPane.margin>
|
||||
@@ -65,6 +62,40 @@
|
||||
<Insets left="30.0" right="30.0" />
|
||||
</GridPane.margin>
|
||||
</GridPane>
|
||||
<GridPane GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="50.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="256.0" minWidth="10.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="50.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Pane fx:id="boatPane" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" />
|
||||
<JFXButton buttonType="RAISED" onAction="#prevBoat" prefHeight="200.0" prefWidth="50.0" text="<" />
|
||||
<JFXButton buttonType="RAISED" onAction="#nextBoat" prefHeight="200.0" prefWidth="50.0" text=">" GridPane.columnIndex="2" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<GridPane GridPane.rowIndex="2">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Max Speed:" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Acceleration:" GridPane.halignment="CENTER" GridPane.rowIndex="1" GridPane.valignment="CENTER" />
|
||||
<Text strokeType="OUTSIDE" strokeWidth="0.0" text="Handling:" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER" />
|
||||
<ProgressBar fx:id="speedBar" focusTraversable="false" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" />
|
||||
<ProgressBar fx:id="accelBar" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<ProgressBar fx:id="handleBar" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXDialogLayout?>
|
||||
<?import com.jfoenix.controls.JFXToggleButton?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<JFXDialogLayout fx:id="keyBindDialog" maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
minHeight="-Infinity" minWidth="-Infinity" prefHeight="580.0" prefWidth="500.0"
|
||||
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="seng302.visualiser.controllers.dialogs.KeyBindingDialogController">
|
||||
<children>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0"/>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="70.0"
|
||||
vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label fx:id="keyBindingDialogHeader" text="CUSTOM KEYBIND" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
|
||||
<Label text="ZOOM IN" GridPane.halignment="CENTER" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<Label text="ZOOM OUT" GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<Label text="VMG" GridPane.halignment="CENTER" GridPane.rowIndex="3"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<Label text="SAILS IN/OUT" GridPane.halignment="CENTER" GridPane.rowIndex="4"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<Label text="TACK/GYBE" GridPane.halignment="CENTER" GridPane.rowIndex="5"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<Label fx:id="upwindLabel" text="UPWIND" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="6" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<Label fx:id="downwindLabel" text="DOWNWIND" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="7" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin></Label>
|
||||
<JFXButton id="ZOOM IN" fx:id="zoomInbtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0" text="Z"
|
||||
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1"
|
||||
GridPane.valignment="CENTER"/>
|
||||
<JFXButton id="ZOOM OUT" fx:id="zoomOutBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0" text="X"
|
||||
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2"
|
||||
GridPane.valignment="CENTER"/>
|
||||
<JFXButton id="VMG" fx:id="vmgBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
||||
text="SPACE" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="3" GridPane.valignment="CENTER"/>
|
||||
<JFXButton id="SAILS IN/OUT" fx:id="sailInOutBtn" buttonType="RAISED"
|
||||
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity"
|
||||
prefWidth="120.0" text="SHIFT" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="4" GridPane.valignment="CENTER"/>
|
||||
<JFXButton id="TACK/GYBE" fx:id="tackGybeBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
||||
text="ENTER" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="5" GridPane.valignment="CENTER"/>
|
||||
<JFXButton id="UPWIND" fx:id="upwindBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
||||
text="PAGE_UP" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="6" GridPane.valignment="CENTER"/>
|
||||
<JFXButton id="DOWNWIND" fx:id="downwindBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
|
||||
text="PAGE_DOWN" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="7" GridPane.valignment="CENTER"/>
|
||||
<JFXToggleButton fx:id="turningToggle" minHeight="-Infinity" prefHeight="35.0"
|
||||
text="OFF / ON" GridPane.columnIndex="1" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="8"/>
|
||||
<Label text="CONTINUOUSLY TURNING" GridPane.halignment="CENTER" GridPane.rowIndex="8"
|
||||
GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets/>
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<JFXButton fx:id="resetBtn" buttonType="RAISED" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0"
|
||||
prefWidth="150.0" text="RESET" GridPane.columnSpan="2" GridPane.halignment="CENTER"
|
||||
GridPane.rowIndex="9" GridPane.valignment="CENTER"/>
|
||||
<Label fx:id="closeLabel" text="✖" translateY="-5.0" GridPane.columnIndex="1"
|
||||
GridPane.halignment="RIGHT" GridPane.valignment="TOP"/>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
<stylesheets>
|
||||
<URL value="@../../css/dialogs/KeyBindingDialog.css" />
|
||||
<URL value="@../../css/Master.css" />
|
||||
</stylesheets>
|
||||
</JFXDialogLayout>
|
||||
@@ -5,6 +5,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.utilities.GeoUtility;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
import static seng302.gameServer.GameState.checkCollision;
|
||||
|
||||
@@ -14,8 +15,10 @@ import static seng302.gameServer.GameState.checkCollision;
|
||||
*/
|
||||
public class UpdateYachtTest {
|
||||
|
||||
private ServerYacht yacht1 = new ServerYacht("Yacht", 1, "1", "Yacht" + 1, "Yacht" + 1, "Test1");
|
||||
private ServerYacht yacht2 = new ServerYacht("Yacht", 2, "2", "Yacht" + 2, "Yacht" + 2, "Test2");
|
||||
private ServerYacht yacht1 = new ServerYacht(BoatMeshType.DINGHY, 1, "1", "Yacht" + 1,
|
||||
"Yacht" + 1, "Test1");
|
||||
private ServerYacht yacht2 = new ServerYacht(BoatMeshType.DINGHY, 2, "2", "Yacht" + 2,
|
||||
"Yacht" + 2, "Test2");
|
||||
private GeoPoint geoPoint1 = new GeoPoint(50.0, 50.0);
|
||||
private GeoPoint geoPoint2 = GeoUtility.getGeoCoordinate(geoPoint1, 90.0, 50.0);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import seng302.gameServer.GameState;
|
||||
import seng302.model.ServerYacht;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
|
||||
public class YachtTest {
|
||||
@@ -17,7 +18,7 @@ public class YachtTest {
|
||||
@BeforeClass
|
||||
public static void setUp() {
|
||||
new GameState("localhost");
|
||||
y1 = new ServerYacht("Yacht", 1, "Y1", "Y1", "Yacht 1", "C1");
|
||||
y1 = new ServerYacht(BoatMeshType.DINGHY, 1, "Y1", "Y1", "Yacht 1", "C1");
|
||||
gs = new GameState("localhost");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
package seng302.serverDiscovery;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import seng302.discoveryServer.util.ServerListing;
|
||||
import seng302.discoveryServer.util.ServerTable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class ServerTableTest {
|
||||
private static ServerTable serverTable;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup(){
|
||||
serverTable = new ServerTable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddServer(){
|
||||
ServerListing listing = new ServerListing("", "", "", 12, 12);
|
||||
serverTable.addServer(listing);
|
||||
|
||||
assertTrue(serverTable.getAllServers().contains(listing));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNextRoomCodeIsUnique(){
|
||||
assertTrue(!Objects.equals(serverTable.getNextRoomCode(), serverTable.getNextRoomCode()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetServerRoomCode(){
|
||||
ServerListing listing = new ServerListing("123", "", "", 12, 12);
|
||||
listing.setRoomCode(serverTable.getNextRoomCode().toString());
|
||||
serverTable.addServer(listing);
|
||||
|
||||
ServerListing result = serverTable.getServerByRoomCode(listing.getRoomCode());
|
||||
|
||||
assertTrue(result.equals(listing));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServersRemovedOnExpiry() throws InterruptedException {
|
||||
ServerListing listing = new ServerListing("432", "221", "", 12, 12);
|
||||
listing.setTtl(1);
|
||||
|
||||
serverTable.addServer(listing);
|
||||
|
||||
listing.decrementTtl();
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
assertTrue(!serverTable.getAllServers().contains(listing));
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package seng302.serverDiscovery;
|
||||
|
||||
import org.junit.Test;
|
||||
import seng302.gameServer.messages.Message;
|
||||
import seng302.gameServer.messages.RoomCodeRequest;
|
||||
import seng302.model.stream.packets.PacketType;
|
||||
import seng302.discoveryServer.util.ServerRepoStreamParser;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class testStreamParser {
|
||||
private static ServerRepoStreamParser parser;
|
||||
private static InputStream inputStream;
|
||||
|
||||
private static void setupWithByteArray(byte[] bytes){
|
||||
inputStream = new ByteArrayInputStream(bytes);
|
||||
parser = new ServerRepoStreamParser(inputStream);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseRoomCodeRequest() throws Exception {
|
||||
Message roomCodeMsg = new RoomCodeRequest("1234");
|
||||
setupWithByteArray(roomCodeMsg.getBuffer());
|
||||
|
||||
assertTrue(parser.parse() == PacketType.ROOM_CODE_REQUEST);
|
||||
assertTrue(parser.getRoomCode().equals("1234"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package seng302.utilities;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* Basic tests for the next and previous methods
|
||||
* Created by kre39 on 20/09/17.
|
||||
*/
|
||||
public class BoatMeshTypeTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testNextBoatMeshType() {
|
||||
BoatMeshType currentBoat = BoatMeshType.DINGHY;
|
||||
BoatMeshType nextBoat = BoatMeshType.getNextBoatType(currentBoat);
|
||||
Assert.assertEquals(BoatMeshType.CATAMARAN, nextBoat);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreviousBoatMeshType() {
|
||||
BoatMeshType currentBoat = BoatMeshType.CATAMARAN;
|
||||
BoatMeshType prevBoat = BoatMeshType.getPrevBoatType(currentBoat);
|
||||
Assert.assertEquals(BoatMeshType.DINGHY, prevBoat);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import seng302.model.ClientYacht;
|
||||
import seng302.visualiser.fxObjects.assets_3D.BoatMeshType;
|
||||
|
||||
/**
|
||||
* Created by kre39 on 6/08/17.
|
||||
@@ -16,7 +17,7 @@ public class BoatSailAnimationToggleTest {
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception{
|
||||
yacht = new ClientYacht("Yacht", 1, "YACHT", "YAC", "Test Yacht", "NZ");
|
||||
yacht = new ClientYacht(BoatMeshType.DINGHY, 1, "YACHT", "YAC", "Test Yacht", "NZ");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -13,6 +13,7 @@ import seng302.model.ServerYacht;
|
||||
import seng302.visualiser.ClientToServerThread;
|
||||
|
||||
/**
|
||||
*
|
||||
* Created by kre39 on 7/08/17.
|
||||
*/
|
||||
public class ToggleSailSteps {
|
||||
|
||||
Reference in New Issue
Block a user