Compare commits

..

10 Commits

Author SHA1 Message Date
Michael Rausch 562d641703 Fixed alignment on room code label, and room code input
Tags: #story[1281]
2017-09-25 20:19:21 +13:00
Michael Rausch ca320f7fb8 Merge remote-tracking branch 'origin/1273_Changing_Cameras' into 1281_Server_Discovery_Internet 2017-09-25 00:18:35 +13:00
Michael Rausch 5e3ae40d03 Made discovery more reliable & added docs/tests
- Added unit tests
- Added documentation for discovery classes
- Improved error handling

Tags: #story[1281]
2017-09-22 00:01:13 +12:00
Michael Rausch 95ad7a4840 Finished implementing room codes.
- Fixed bug where room code wasn't parsed correctly
- Added room code selection to server list screen.
- Added room code to hosts lobby.
- Implemented communication protocols on the game client.

Tags: #story[1281]
2017-09-21 22:48:33 +12:00
Alistair McIntyre 6ff309a40c - Perspective Camera Works
- Top Down Camera Works
- Started on chase cam but the math is a bit tricky.

tags : #story[1273]
2017-09-21 14:40:35 +12:00
Michael Rausch e17e9749d8 Implemented server to manage a list of available servers on the internet.
- Implemented a server manager that keeps track of servers & room codes, and removes old servers
- Implemented queries to find a server with a specific room code
- Implemented protocol to register servers

#story[1281]
2017-09-20 20:26:14 +12:00
William Muir 034e4c252a Icons now display, blink when they are about to run off, and turn off after their time out
TokenType Enum now also has a timeout construction field
#story[1245]
2017-09-20 13:09:09 +12:00
William Muir 6cde016401 Fixed random token assigning and realisation
Token class now has two functions: assignRandomType and realiseRandomType
The former can be used to assign any random type to the token including the random type
The latter can be used to assign a concrete random type to the token (not the random type)

#story[1245]
2017-09-20 12:02:12 +12:00
William Muir 52d3cea592 Added preliminary icons for pickups
RaceView now has a grid pane to contain some icons to display power ups. These are just preliminary

ClientYacht now has a power up field that is set from recieveing messages in the Game Client, as well as observed by the RaceViewController to display the relevant icon when the powerup field is changed

#story[1245]
2017-09-19 23:04:17 +12:00
William Muir 78596ea111 Initial commit for Power Up story
Made new preliminary models for each power up. Currently just different colour balls
Added new YachtEventTypes in the enum for each pick up to be sent out to clients
Tokens now not only randomise location but also randomise which type of token will be sent out
Added new methods to the MessageFactory class - Make collision and Make pickup Message
Game Client now checks what type of Yacht Event code has come in to respond appropriately rather than just generic collision / token.. although this has not been implemented yet
Game View loads appropriate token models depending on what is in XML

#story[1245]
2017-09-19 17:47:05 +12:00
60 changed files with 2483 additions and 159 deletions
+20 -1
View File
@@ -10,11 +10,13 @@ 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();
@@ -25,9 +27,21 @@ 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")) {
@@ -67,15 +81,20 @@ public class App extends Application {
}
public static void main(String[] args) {
public static void main(String[] args) throws Exception {
try {
parseArgs(args);
} catch (ParseException e) {
logger.error("Could not parse command line arguments");
}
if (!isRunningAsCache){
launch(args);
}
else{
new DiscoveryServer();
}
}
}
@@ -0,0 +1,117 @@
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;
}
}
}
}
@@ -0,0 +1,121 @@
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;
}
}
@@ -0,0 +1,50 @@
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;
}
}
@@ -0,0 +1,113 @@
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;
}
}
@@ -0,0 +1,109 @@
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;
}
}
@@ -0,0 +1,97 @@
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;
}
}
+19 -16
View File
@@ -47,6 +47,7 @@ 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;
@@ -281,7 +282,12 @@ public class GameState implements Runnable {
public static void spawnNewToken() {
Random random = new Random();
tokensInPlay.clear();
tokensInPlay.add(allTokens.get(random.nextInt(allTokens.size())));
//Get a random token location with random type
Token token = allTokens.get(random.nextInt(allTokens.size()));
token.assignRandomType();
tokensInPlay.add(token);
}
/**
@@ -382,6 +388,7 @@ 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();
@@ -397,9 +404,7 @@ public class GameState implements Runnable {
collidedYacht.setCurrentVelocity(
collidedYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
);
notifyMessageListeners(
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION)
);
notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht));
}
//Mark Collision
@@ -411,9 +416,7 @@ public class GameState implements Runnable {
serverYacht.setCurrentVelocity(
serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
);
notifyMessageListeners(
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION)
);
notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht));
}
//Boundary Collision
@@ -426,22 +429,23 @@ public class GameState implements Runnable {
serverYacht.setCurrentVelocity(
serverYacht.getCurrentVelocity() * COLLISION_VELOCITY_PENALTY
);
notifyMessageListeners(
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.COLLISION)
);
notifyMessageListeners(MessageFactory.makeCollisionMessage(serverYacht));
}
//Token Collision
Token collidedToken = checkTokenPickUp(serverYacht);
if (collidedToken != null) {
sendServerMessage(serverYacht.getSourceId(), serverYacht.getBoatName() + " has picked speed-up token");
if (collidedToken.getTokenType() == TokenType.RANDOM) {
collidedToken.realiseRandom();
}
sendServerMessage(serverYacht.getSourceId(),
serverYacht.getBoatName() + " has picked up a " + collidedToken.getTokenType()
.getName() + " token");
tokensInPlay.remove(collidedToken);
serverYacht.powerUp(collidedToken.getTokenType());
logger.debug("Yacht: " + serverYacht.getShortName() + " got powerup " + collidedToken
.getTokenType());
notifyMessageListeners(MessageFactory.getRaceXML());
notifyMessageListeners(
new YachtEventCodeMessage(serverYacht.getSourceId(), YachtEventType.TOKEN));
notifyMessageListeners(MessageFactory.makePickupMessage(serverYacht, collidedToken));
}
}
@@ -452,8 +456,7 @@ public class GameState implements Runnable {
Double maxBoatSpeed = GeoUtility.knotsToMMS(boatSpeedInKnots) * speedMultiplier;
if (yacht.getPowerUp() != null) {
if (yacht.getPowerUp().equals(TokenType.BOOST)) {
// TODO: 11/09/17 wmu16 CHANGE THIS TO MAGIC NUMBER
maxBoatSpeed *= 2;
maxBoatSpeed *= VELOCITY_BOOST_MULTIPLIER;
}
}
@@ -11,11 +11,14 @@ 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;
/**
@@ -128,4 +131,30 @@ 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,5 +1,8 @@
package seng302.gameServer;
import seng302.discoveryServer.util.ServerListing;
import seng302.discoveryServer.DiscoveryServerClient;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;
import java.io.IOException;
@@ -32,12 +35,15 @@ 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");
@@ -126,6 +132,9 @@ public class ServerAdvertiser {
}
}
}, 0);
ServerListing serverListing = new ServerListing(serverName, props.get("map"), getLocalHostIp(), portNo, Integer.parseInt(props.get("capacity")));
repositoryClient.register(serverListing);
}
/**
@@ -7,6 +7,10 @@ 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;
@@ -15,6 +19,7 @@ public class ServerDescription {
this.address = address;
this.portNum = portNum;
this.capacity = capacity;
lastUpdated = System.currentTimeMillis();
}
@@ -80,4 +85,20 @@ 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();
}
}
@@ -21,7 +21,10 @@ public enum MessageType {
REGISTRATION_REQUEST(101),
REGISTRATION_RESPONSE(102),
CUSTOMIZATION_REQUEST(103),
CUSTOMIZATION_RESPONSE(104);
CUSTOMIZATION_RESPONSE(104),
REPO_REGISTRATION_REQUEST(201),
ROOM_CODE_REQUEST(202),
LOBBY_REQUEST(203);
private int code;
@@ -0,0 +1,24 @@
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();
}
}
@@ -0,0 +1,60 @@
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,7 +5,11 @@ package seng302.gameServer.messages;
*/
public enum YachtEventType {
COLLISION(33),
TOKEN(34);
TOKEN_VELOCITY(34),
TOKEN_BUMPER(35),
TOKEN_HANDLING(36),
TOKEN_WIND_WALKER(37),
TOKEN_RANDOM(38);
private int code;
@@ -12,9 +12,14 @@ 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;
/**
* Yacht class for the racing boat. <p> Class created to store more variables (eg. boat statuses)
@@ -34,6 +39,11 @@ 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);
@@ -44,6 +54,7 @@ public class ClientYacht extends Observable {
private String boatName;
private String country;
private Integer position;
private TokenType powerUp;
private Long estimateTimeAtFinish;
private Boolean sailIn = false;
@@ -56,8 +67,11 @@ 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();
@@ -199,6 +213,17 @@ 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;
}
@@ -268,6 +293,10 @@ public class ClientYacht extends Observable {
markRoundingListeners.add(listener);
}
public void addPowerUpListener(PowerUpListener listener) {
powerUpListeners.add(listener);
}
public void removeMarkRoundingListener(MarkRoundingListener listener) {
markRoundingListeners.remove(listener);
}
@@ -288,4 +317,12 @@ public class ClientYacht extends Observable {
public Double getCurrentVelocity() {
return currentVelocity;
}
public void setBoatObject(BoatObject newBoatObject) {
this.boatObject = newBoatObject;
}
public BoatObject getBoatObject() {
return this.boatObject;
}
}
@@ -20,7 +20,9 @@ public enum PacketType {
RACE_REGISTRATION_REQUEST,
RACE_REGISTRATION_RESPONSE,
RACE_CUSTOMIZATION_REQUEST,
RACE_CUSTOMIZATION_RESPONSE;
RACE_CUSTOMIZATION_RESPONSE,
SERVER_REGISTRATION, ROOM_CODE_REQUEST, LOBBY_REQUEST;
public static PacketType assignPacketType(int packetType, byte[] payload){
switch(packetType){
@@ -65,6 +67,10 @@ 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,5 +1,9 @@
package seng302.model.token;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import seng302.model.GeoPoint;
/**
@@ -9,6 +13,7 @@ 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);
@@ -18,4 +23,22 @@ 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,27 +5,32 @@ package seng302.model.token;
* Created by wmu16 on 28/08/17.
*/
public enum TokenType {
BOOST(0),
HANDLING(1);
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);
private int value;
private String name;
private int timeout;
TokenType(int value) {
TokenType(int value, String name, int timeout) {
this.value = value;
this.name = name;
this.timeout = timeout;
}
public int getValue() {
return value;
}
public static TokenType getToken(int value) {
switch (value) {
case 0:
return BOOST;
case 1:
return HANDLING;
default:
return BOOST;
public String getName() {
return name;
}
public int getTimeout() {
return timeout;
}
}
@@ -37,6 +37,7 @@ 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;
@@ -245,12 +246,7 @@ public class GameClient {
break;
case YACHT_EVENT_CODE:
YachtEventData yachtEventData = StreamParser.extractYachtEventCode(packet);
if (yachtEventData.getEventId() == YachtEventType.COLLISION.getCode()) {
showCollisionAlert(StreamParser.extractYachtEventCode(packet));
} else if (yachtEventData.getEventId() == YachtEventType.TOKEN.getCode()) {
showPickUp();
}
processYachtEvent(StreamParser.extractYachtEventCode(packet));
break;
case CHATTER_TEXT:
@@ -407,6 +403,34 @@ 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.
*/
@@ -420,8 +444,18 @@ public class GameClient {
}
// TODO: 11/09/17 wmu16 - Add in functionality to viually indicate a pickup to a user
private void showPickUp() {
private void showTokenPickUp(TokenType tokenType) {
Sounds.playTokenPickupSound();
switch (tokenType) {
case BOOST:
break;
case HANDLING:
break;
case WIND_WALKER:
break;
case BUMPER:
break;
}
}
private void formatAndSendChatMessage(String rawChat) {
@@ -27,8 +27,14 @@ 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.BoatObject;
import seng302.visualiser.fxObjects.assets_3D.Marker3D;
@@ -51,6 +57,8 @@ public class GameView3D {
private SubScene view;
// ParallelCamera camera;
private PerspectiveCamera camera;
private PerspectiveCamera camera2;
private PerspectiveCamera camera3;
private Group gameObjects;
private double bufferSize = 0;
@@ -87,13 +95,21 @@ public class GameView3D {
}
public GameView3D () {
camera = new PerspectiveCamera(true);
camera.getTransforms().addAll(
new Translate(DEFAULT_CAMERA_X,DEFAULT_CAMERA_Y, DEFAULT_CAMERA_DEPTH)
);
camera = new IsometricCamera(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(
@@ -405,35 +421,46 @@ public class GameView3D {
public void cameraMovement(KeyEvent event) {
switch (event.getCode()) {
case NUMPAD8:
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(1,0,0)));
view.getCamera().getTransforms().addAll(new Rotate(0.5, new Point3D(1, 0, 0)));
break;
case NUMPAD2:
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(1,0,0)));
view.getCamera().getTransforms().addAll(new Rotate(-0.5, new Point3D(1, 0, 0)));
break;
case NUMPAD4:
camera.getTransforms().addAll(new Rotate(-0.5, new Point3D(0,1,0)));
view.getCamera().getTransforms().addAll(new Rotate(-0.5, new Point3D(0, 1, 0)));
break;
case NUMPAD6:
camera.getTransforms().addAll(new Rotate(0.5, new Point3D(0,1,0)));
view.getCamera().getTransforms().addAll(new Rotate(0.5, new Point3D(0, 1, 0)));
break;
case Z:
camera.getTransforms().addAll(new Translate(0, 0, 1.5));
((RaceCamera) view.getCamera()).zoomIn();
break;
case X:
camera.getTransforms().addAll(new Translate(0, 0, -1.5));
((RaceCamera) view.getCamera()).zoomOut();
break;
case W:
camera.getTransforms().addAll(new Translate(0, -1, 0));
view.getCamera().getTransforms().addAll(new Translate(0, -1, 0));
break;
case S:
camera.getTransforms().addAll(new Translate(0, 1, 0));
view.getCamera().getTransforms().addAll(new Translate(0, 1, 0));
break;
case A:
camera.getTransforms().addAll(new Translate(-1, 0, 0));
view.getCamera().getTransforms().addAll(new Translate(-1, 0, 0));
break;
case D:
camera.getTransforms().addAll(new Translate(1, 0, 0));
view.getCamera().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);
}
}
}
@@ -470,6 +497,11 @@ 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);
@@ -556,7 +588,27 @@ public class GameView3D {
mapTokens = new ArrayList<>();
for (Token token : newTokens) {
Point2D location = findScaledXY(token.getLat(), token.getLng());
Node tokenObject = ModelFactory.importModel(ModelType.VELOCITY_PICKUP).getAssets();
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();
tokenObject.setLayoutX(location.getX());
tokenObject.setLayoutY(location.getY());
mapTokens.add(tokenObject);
@@ -6,11 +6,10 @@ 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.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import static seng302.gameServer.ServerAdvertiser.getLocalHostIp;
@@ -18,6 +17,7 @@ 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,8 +91,16 @@ 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 {
@@ -110,4 +118,25 @@ 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));
}
}
}
}
@@ -0,0 +1,89 @@
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() {
}
}
@@ -0,0 +1,47 @@
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));
}
}
@@ -0,0 +1,18 @@
package seng302.visualiser.cameras;
public interface RaceCamera {
void zoomIn();
void zoomOut();
void panLeft();
void panRight();
void panUp();
void panDown();
}
@@ -0,0 +1,48 @@
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,6 +22,7 @@ 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;
@@ -29,10 +30,7 @@ import seng302.visualiser.controllers.dialogs.BoatCustomizeController;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.*;
public class LobbyController implements Initializable {
@@ -85,6 +83,10 @@ 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());
@@ -242,4 +244,8 @@ public class LobbyController implements Initializable {
public void closeCustomizationDialog() {
customizationDialog.close();
}
public void setRoomCode(String roomCode) {
roomLabel.setText("Room#" + roomCode);
}
}
@@ -20,6 +20,8 @@ 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;
@@ -47,10 +49,12 @@ 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;
@@ -60,6 +64,8 @@ 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
@@ -67,6 +73,8 @@ import seng302.visualiser.fxObjects.assets_3D.BoatObject;
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;
@@ -110,6 +118,8 @@ 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;
@@ -222,6 +232,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
return finishScreenDialog;
}
public void loadRace (
Map<Integer, ClientYacht> participants, RaceXMLData raceData, RaceState raceState,
ClientYacht player) {
@@ -241,6 +252,8 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
}
});
player.addPowerUpListener(this::displayPowerUpIcon);
updateOrder(raceState.getPlayerPositions());
gameView = new GameView3D();
// gameView.setFrameRateFXText(fpsDisplay);
@@ -279,6 +292,62 @@ 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
*
@@ -15,6 +15,7 @@ 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;
@@ -22,7 +23,10 @@ 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;
@@ -51,6 +55,10 @@ 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;
@@ -64,6 +72,17 @@ 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();
@@ -150,6 +169,24 @@ 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.
*/
@@ -233,8 +233,9 @@ public class ViewManager {
logger.error("Could not load lobby view");
}
if (disableReadyButton) {
LobbyController lobbyController = loader.getController();
if (disableReadyButton) {
lobbyController.disableReadyButton();
}
@@ -245,7 +246,6 @@ 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
@@ -37,7 +37,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.PIRATE_SHIP, this.boatColor);
BoatModel bo = ModelFactory.boatIconView(BoatMeshType.DINGHY, this.boatColor);
group.getChildren().add(bo.getAssets());
}
@@ -2,29 +2,21 @@ 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, jib file, fixed sail)
* ENUM_VALUE (hull file, mast file, Y offset of mast CoR from origin, sail file, Y offset of sail CoR from origin)
* Files must be valid .stl files.
*/
public enum BoatMeshType {
DINGHY("dinghy_hull.stl", "dinghy_mast.stl", 1.36653, "dinghy_sail.stl", 1.36653, null, false),
CAT_ATE_A_MERINGUE("catamaran_hull.stl", "catamaran_mast.stl", 0.997, "catamaran_sail.stl",
0.997, null, false),
PIRATE_SHIP("pirateship_hull.stl", "pirateship_mast.stl", -0.5415, "pirateship_mainsail.stl",
-0.5415, "pirateship_frontsail.stl", true);
DINGHY ("dinghy_hull.stl", "dinghy_mast.stl", -1.36653, "dinghy_sail.stl", -1.36653);
final String hullFile, mastFile, sailFile, jibFile;
final String hullFile, mastFile, sailFile;
final double mastOffset, sailOffset;
final boolean fixedSail;
BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile,
double sailOffset, String jibFile, boolean fixedSail) {
BoatMeshType(String hullFile, String mastFile, double mastOffset, String sailFile, double sailOffset) {
this.hullFile = hullFile;
this.mastFile = mastFile;
this.mastOffset = mastOffset;
this.sailFile = sailFile;
this.sailOffset = sailOffset;
this.jibFile = jibFile;
this.fixedSail = fixedSail;
}
}
@@ -34,17 +34,15 @@ 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, 0, -meshType.mastOffset, 0, new Point3D(0, 0, 1))
new Rotate(degrees, -meshType.mastOffset, 0,0, new Point3D(0, 0, 1))
);
sail.getTransforms().setAll(
new Rotate(degrees, 0, -meshType.sailOffset,0, new Point3D(0, 0, 1))
new Rotate(degrees, -meshType.sailOffset, 0,0, new Point3D(0, 0, 1))
);
}
}
public void hideSail() {
getMeshViewChild(SAIL_INDEX).setVisible(false);
@@ -28,7 +28,7 @@ public class BoatObject extends Group {
private Group wake;
private Color colour = Color.BLACK;
private Boolean isSelected = false;
private Rotate rotation = new Rotate(0, new Point3D(0,0,1));
private Rotate rotation = new Rotate(0,0,1);
private List<SelectedBoatListener> selectedBoatListenerListeners = new ArrayList<>();
@@ -36,7 +36,7 @@ public class BoatObject extends Group {
* Creates a BoatGroup with the default triangular boat polygon.
*/
public BoatObject() {
boatAssets = ModelFactory.boatGameView(BoatMeshType.PIRATE_SHIP, colour);
boatAssets = ModelFactory.boatGameView(BoatMeshType.DINGHY, colour);
boatAssets.hideSail();
boatAssets.getAssets().getTransforms().addAll(
rotation
@@ -66,6 +66,8 @@ 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);
@@ -84,29 +84,20 @@ public class ModelFactory {
}
private static Group getUnmodifiedBoatModel(BoatMeshType boatType, Color primaryColour) {
Group boatAssets = new Group();
MeshView hull = importSTL(boatType.hullFile);
MeshView hull = importFile(boatType.hullFile);
hull.setMaterial(new PhongMaterial(primaryColour));
MeshView mast = importSTL(boatType.mastFile);
MeshView mast = importFile(boatType.mastFile);
mast.setMaterial(new PhongMaterial(primaryColour));
MeshView sail = importSTL(boatType.sailFile);
MeshView sail = importFile(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 importSTL(String fileName) {
private static MeshView importFile(String fileName) {
StlMeshImporter importer = new StlMeshImporter();
importer.read(ModelFactory.class.getResource("/meshes/boatSTLs/" + fileName));
importer.read(ModelFactory.class.getResource("/meshes/" + fileName));
MeshView importedFile = new MeshView(importer.getImport());
importedFile.setCache(true);
importedFile.setCacheHint(CacheHint.SCALE_AND_ROTATE);
@@ -126,7 +117,11 @@ public class ModelFactory {
}
switch (tokenType) {
case VELOCITY_PICKUP:
return makeCoinPickup(assets);
case BUMPER_PICKUP:
case RANDOM_PICKUP:
case HANDLING_PICKUP:
case WIND_WALKER_PICKUP:
return makeTokenPickup(assets);
case FINISH_MARKER:
case PLAIN_MARKER:
case START_MARKER:
@@ -155,24 +150,22 @@ public class ModelFactory {
}
}
private static Model makeCoinPickup(Group assets){
assets.setRotationAxis(new Point3D(1,0,0));
assets.setRotate(90);
assets.setTranslateX(0.2);
assets.setTranslateY(1);
private static Model makeTokenPickup(Group assets) {
Rotate animationRotate = new Rotate(0, new Point3D(0, 0, 1));
assets.getTransforms().addAll(
new Translate(0,-1,0),
new Rotate(0 ,new Point3D(1,1,1))
animationRotate,
new Translate(0, 0, -1)
);
return new Model(new Group(assets), new AnimationTimer() {
private double rotation = 0;
private Group group = assets;
private Rotate rotate = animationRotate;
@Override
public void handle(long now) {
rotation += 1;
((Rotate) group.getTransforms().get(1)).setAngle(rotation);
rotate.setAngle(rotation);
}
});
}
@@ -7,6 +7,10 @@ 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"),
@@ -0,0 +1,108 @@
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());
}
}
+6 -6
View File
@@ -38,30 +38,30 @@
-fx-font-size: 23px;
}
#connectButton {
#connectButton, #roomConnectButton {
-fx-background-color: -fx-pp-light-text-color; /* inverted */
-fx-text-fill: -fx-pp-theme-color; /* inverted */
-fx-font-size: 20px;
-fx-pref-height: 65px;
-fx-pref-height: 45px;
}
#connectButton:hover {
#connectButton:hover, #roomConnectButton:hover {
-fx-font-size: 23px;
}
#connectLabel, #serverPortNumber, #serverHostName {
#connectLabel, #connectLabel1, #serverPortNumber, #roomNumber, #serverHostName {
-fx-text-fill: -fx-pp-light-text-color;
-fx-font-size: 18px;
}
#serverHostName, #serverPortNumber {
#serverHostName, #serverPortNumber, #roomNumber {
-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 {
#serverHostName .error-label, #serverPortNumber .error-label, #roomNumber .error-label {
-fx-font-size: 12px;
-fx-text-fill: lightblue;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+147
View File
@@ -0,0 +1,147 @@
<?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.
+332
View File
@@ -0,0 +1,332 @@
<?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>
@@ -0,0 +1,147 @@
<?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>
@@ -0,0 +1,147 @@
<?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>
+11 -2
View File
@@ -52,10 +52,19 @@
<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" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<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>
<rowConstraints>
<RowConstraints maxHeight="1.7976931348623157E308" minHeight="50.0" prefHeight="74.0" vgrow="SOMETIMES" />
+61
View File
@@ -1,5 +1,14 @@
<?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?>
@@ -14,6 +23,7 @@
<?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"
@@ -235,6 +245,57 @@
<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>
+32 -15
View File
@@ -1,5 +1,11 @@
<?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?>
@@ -12,35 +18,48 @@
<?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.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.rowIndex="1" 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.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.rowIndex="1" 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.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.rowIndex="1" 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.valignment="CENTER">
<Label fx:id="connectLabel" text="Direct Connect:" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="1" 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" />
@@ -51,6 +70,7 @@
<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>
@@ -76,12 +96,9 @@
<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"/>
<Insets right="50.0" />
</GridPane.margin>
</JFXButton>
</children>
@@ -99,11 +116,11 @@
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.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 maxHeight="1.7976931348623157E308" minHeight="400.0" prefHeight="465.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0" vgrow="SOMETIMES" />
</rowConstraints>
<stylesheets>
<String fx:value="/css/Master.css"/>
<String fx:value="/css/Master.css" />
<String fx:value="/css/ServerListView.css" />
</stylesheets>
</GridPane>
@@ -0,0 +1,57 @@
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));
}
}
@@ -0,0 +1,31 @@
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"));
}
}