fix server only drawcells

This commit is contained in:
austin 2022-05-04 23:30:41 -04:00
parent 2c42b51907
commit 53242a5280
6 changed files with 191 additions and 79 deletions

View File

@ -158,6 +158,8 @@ public class LoadingThread extends Thread {
initMicroSimulation();
//collision engine
initCommonWorldData(Globals.RUN_SERVER);
//init draw cell manager
initDrawCellManager();
//init game specific stuff (ie different skybox colors)
initGameGraphicalEntities();
//set simulations to ready if they exist
@ -187,6 +189,8 @@ public class LoadingThread extends Thread {
initServerThread();
//collision engine
initCommonWorldData(Globals.RUN_SERVER);
//init draw cell manager
initDrawCellManager();
//initialize the "virtual" objects simulation
//not really relevant in arena mode
// initMacroSimulation();
@ -358,7 +362,7 @@ public class LoadingThread extends Thread {
static void initServerArenaWorldData(){
Globals.serverWorldData = ServerWorldData.createArenaWorld();
Globals.spawnPoint = new Vector3d(1,2.0,1);
Globals.spawnPoint = new Vector3d(1,0.1,1);
// Globals.serverTerrainManager.getChunk(0, 0).addModification(new TerrainModification(0,0,5,5,5));
}
@ -412,6 +416,7 @@ public class LoadingThread extends Thread {
Thread clientThread = null;
if(Globals.RUN_CLIENT){
Globals.clientConnection = new ClientNetworking(NetUtils.getAddress(),NetUtils.getPort());
System.out.println(Globals.clientConnection.socket);
clientThread = new Thread(Globals.clientConnection);
clientThread.start();
}
@ -419,37 +424,44 @@ public class LoadingThread extends Thread {
static void initDrawCellManager(){
Globals.drawCellManager = new DrawCellManager(
Globals.clientWorldData,
Globals.clientTerrainManager,
Globals.clientPlayerData.getWorldPositionX(),
Globals.clientPlayerData.getWorldPositionY()
// Globals.terrainManager.getDynamicInterpolationRatio(),
// Globals.terrainManager.getRandomDampener()
);
while(Globals.drawCellManager.containsInvalidCell()){
// Globals.drawCellManager.updateInvalidCell();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
// System.out.println("invalid cell");
if(Globals.drawCellManager == null){
Globals.drawCellManager = new DrawCellManager(
Globals.commonWorldData,
Globals.clientTerrainManager,
Globals.clientPlayerData.getWorldPositionX(),
Globals.clientPlayerData.getWorldPositionY()
// Globals.terrainManager.getDynamicInterpolationRatio(),
// Globals.terrainManager.getRandomDampener()
);
} else {
//set our draw cell manager to actually generate drawable chunks
Globals.drawCellManager.setGenerateDrawables(true);
}
while(Globals.drawCellManager.containsUndrawableCell()){
// Globals.drawCellManager.makeCellDrawable();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
//wait for all the terrain data to arrive
if(Globals.RUN_CLIENT){
while(Globals.drawCellManager.containsInvalidCell()){
// Globals.drawCellManager.updateInvalidCell();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
// System.out.println("invalid cell");
}
// System.out.println("undrawable");
}
while(Globals.drawCellManager.containsPhysicsNeedingCell()){
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
while(Globals.drawCellManager.containsUndrawableCell()){
// Globals.drawCellManager.makeCellDrawable();
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
// System.out.println("undrawable");
}
while(Globals.drawCellManager.containsPhysicsNeedingCell()){
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException ex) {
}
}
}
System.out.println("Draw Cell Manager ready");

View File

@ -78,6 +78,20 @@ public class EntityUtils {
Globals.entityManager.registerUIEntity(rVal);
return rVal;
}
/**
* Spawns an entity that has a position in the world, but isn't necessarily drawable
* @return the entity
*/
public static Entity spawnSpatialEntity(){
Entity rVal = new Entity();
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
Globals.entityManager.registerEntity(rVal);
return rVal;
}
public static void cleanUpDrawableEntity(Entity e){
if(e != null){

View File

@ -125,6 +125,13 @@ public class DrawCell {
}
public void generatePhysics(){
//if we're in no-graphics mode, need to generate the entity
if(modelEntity == null){
modelEntity = EntityUtils.spawnSpatialEntity();
modelEntity.putData(EntityDataStrings.TERRAIN_IS_TERRAIN, true);
EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio));
}
//then actually perform the attach
physicsObject = PhysicsUtils.attachTerrainRigidBody(modelEntity,heightmap);
Globals.collisionEngine.registerPhysicsEntity(modelEntity);
// System.out.println("generate physics");

View File

@ -2,7 +2,9 @@ package electrosphere.game.client.cells;
import electrosphere.game.client.terrain.manager.ClientTerrainManager;
import electrosphere.game.server.terrain.manager.ServerTerrainManager;
import electrosphere.game.terrain.processing.TerrainInterpolator;
import electrosphere.game.client.world.ClientWorldData;
import electrosphere.game.collision.CommonWorldData;
import electrosphere.main.Globals;
import electrosphere.net.parser.net.message.TerrainMessage;
import electrosphere.renderer.ShaderProgram;
@ -54,22 +56,25 @@ public class DrawCellManager {
int worldBoundDiscreteMax = 0;
//metadata about the game world
ClientWorldData clientWorldData;
CommonWorldData commonWorldData;
//client terrain manager
ClientTerrainManager clientTerrainManager;
// ClientTerrainManager clientTerrainManager;
//ready to start updating?
boolean update = false;
//controls whether we try to generate the drawable entities
//we want this to be false when in server-only mode
boolean generateDrawables = false;
public DrawCellManager(ClientWorldData clientWorldData, ClientTerrainManager clientTerrainManager, int discreteX, int discreteY){
this.clientWorldData = clientWorldData;
worldBoundDiscreteMax = (int)(this.clientWorldData.getWorldBoundMax().x / this.clientWorldData.getDynamicInterpolationRatio() * 1.0f);
this.clientTerrainManager = clientTerrainManager;
this.miniCellWidth = miniCellWidth;
public DrawCellManager(CommonWorldData commonWorldData, ClientTerrainManager clientTerrainManager, int discreteX, int discreteY){
this.commonWorldData = commonWorldData;
worldBoundDiscreteMax = (int)(commonWorldData.getWorldBoundMin().x / commonWorldData.getDynamicInterpolationRatio() * 1.0f);
// this.clientTerrainManager = clientTerrainManager;
cells = new DrawCell[drawRadius * 2 + 1][drawRadius * 2 + 1];
valid = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
drawable = new boolean[drawRadius * 2 + 1][drawRadius * 2 + 1];
@ -148,17 +153,17 @@ public class DrawCellManager {
if(
currentCellX >= 0 &&
currentCellX < clientWorldData.getWorldDiscreteSize() &&
currentCellX < commonWorldData.getWorldDiscreteSize() &&
currentCellY >= 0 &&
currentCellY < clientWorldData.getWorldDiscreteSize()
currentCellY < commonWorldData.getWorldDiscreteSize()
){
if(clientTerrainManager.containsHeightmapAtDiscretePoint(currentCellX, currentCellY)){
if(containsHeightmapAtDiscretePoint(currentCellX, currentCellY)){
cells[targetX][targetY] = DrawCell.generateTerrainCell(
currentCellX,
currentCellY,
clientTerrainManager.getHeightmapAtPoint(currentCellX, currentCellY),
clientTerrainManager.getTextureMapAtPoint(currentCellX, currentCellY),
clientWorldData.getDynamicInterpolationRatio(),
getHeightmapAtPoint(currentCellX, currentCellY),
getTextureMapAtPoint(currentCellX, currentCellY),
commonWorldData.getDynamicInterpolationRatio(),
program
);
valid[targetX][targetY] = true;
@ -207,9 +212,9 @@ public class DrawCellManager {
int currentCellY = cellY - drawRadius + targetY;
if(
currentCellX >= 0 &&
currentCellX < clientWorldData.getWorldDiscreteSize() &&
currentCellX < commonWorldData.getWorldDiscreteSize() &&
currentCellY >= 0 &&
currentCellY < clientWorldData.getWorldDiscreteSize()
currentCellY < commonWorldData.getWorldDiscreteSize()
){
//physics radius calculation
// if(Math.abs(physicsRadius + 1 - targetX) < physicsRadius && Math.abs(physicsRadius + 1 - targetY) < physicsRadius){
@ -217,8 +222,8 @@ public class DrawCellManager {
// }
//calculation for stride
int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius));//Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
int stride = Math.min(clientWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
while(clientWorldData.getDynamicInterpolationRatio() % stride != 0){
int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){
stride = stride + 1;
}
//make drawable entity
@ -251,16 +256,16 @@ public class DrawCellManager {
int currentCellY = cellY - drawRadius + targetY;
if(
currentCellX >= 0 &&
currentCellX < clientWorldData.getWorldDiscreteSize() &&
currentCellX < commonWorldData.getWorldDiscreteSize() &&
currentCellY >= 0 &&
currentCellY < clientWorldData.getWorldDiscreteSize()
currentCellY < commonWorldData.getWorldDiscreteSize()
){
// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){
// needsPhysics[targetX][targetY] = true;
// }
int dist = (int)Math.sqrt((targetX - drawRadius)*(targetX - drawRadius) + (targetY - drawRadius) * (targetY - drawRadius)); //Math.abs(targetX - drawRadius) * Math.abs(targetY - drawRadius);
int stride = Math.min(clientWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
while(clientWorldData.getDynamicInterpolationRatio() % stride != 0){
int stride = Math.min(commonWorldData.getDynamicInterpolationRatio()/2, Math.max(1, dist / drawStepdownInterval * drawStepdownValue));
while(commonWorldData.getDynamicInterpolationRatio() % stride != 0){
stride = stride + 1;
}
cells[targetX][targetY].generateDrawableEntity(stride);
@ -289,7 +294,7 @@ public class DrawCellManager {
public boolean containsUndrawableCell(){
for(int x = 0;x < drawRadius * 2 + 1; x++){
for(int y = 0; y < drawRadius * 2 + 1; y++){
if(!drawable[x][y]){
if(!drawable[x][y] && this.generateDrawables){
return true;
}
}
@ -300,7 +305,7 @@ public class DrawCellManager {
public boolean containsUpdateableCell(){
for(int x = 0;x < drawRadius * 2 + 1; x++){
for(int y = 0; y < drawRadius * 2 + 1; y++){
if(updateable[x][y]){
if(updateable[x][y] && this.generateDrawables){
return true;
}
}
@ -343,9 +348,9 @@ public class DrawCellManager {
int currentCellY = cellY - physicsRadius + targetY;
if(
currentCellX >= 0 &&
currentCellX < clientWorldData.getWorldDiscreteSize() &&
currentCellX < commonWorldData.getWorldDiscreteSize() &&
currentCellY >= 0 &&
currentCellY < clientWorldData.getWorldDiscreteSize()
currentCellY < commonWorldData.getWorldDiscreteSize()
){
// if(Math.abs(drawRadius + 1 - targetX) < physicsRadius && Math.abs(drawRadius + 1 - targetY) < physicsRadius){
// needsPhysics[targetX][targetY] = true;
@ -530,7 +535,7 @@ public class DrawCellManager {
public int transformRealSpaceToCellSpace(double input){
return (int)(input / clientWorldData.getDynamicInterpolationRatio());
return (int)(input / commonWorldData.getDynamicInterpolationRatio());
}
@ -647,6 +652,46 @@ public class DrawCellManager {
public boolean coordsInPhysicsSpace(int worldX, int worldY){
return worldX <= cellX + physicsRadius && worldX >= cellX - physicsRadius && worldY <= cellY + physicsRadius && worldY >= cellY - physicsRadius;
}
public void setGenerateDrawables(boolean generate){
this.generateDrawables = generate;
}
boolean containsHeightmapAtDiscretePoint(int currentCellX, int currentCellY){
if(Globals.clientTerrainManager != null){
return Globals.clientTerrainManager.containsHeightmapAtDiscretePoint(currentCellX, currentCellY);
}
return true;
}
float[][] getHeightmapAtPoint(int currentCellX, int currentCellY){
if(Globals.clientTerrainManager != null){
return Globals.clientTerrainManager.getHeightmapAtPoint(currentCellX, currentCellY);
}
return Globals.serverTerrainManager.getChunk(currentCellX, currentCellY).getHeightMap();
}
float[][] getTextureMapAtPoint(int currentCellX, int currentCellY){
if(Globals.clientTerrainManager != null){
return Globals.clientTerrainManager.getTextureMapAtPoint(currentCellX,currentCellY);
} else {
//hacky fix to +2 to this, I think the interpolation ratio was different for server/client data
//now that we're merging/ambiguous within this class, it's out of bounds-ing unless I +2
//TODO: investigate
float[][] rVal = new float[commonWorldData.getDynamicInterpolationRatio() + 2][commonWorldData.getDynamicInterpolationRatio() + 2];
rVal[1][1] = 1;
rVal[2][1] = 1;
rVal[3][1] = 1;
rVal[4][1] = 1;
rVal[5][1] = 1;
rVal[5][2] = 1;
rVal[6][1] = 1;
rVal[6][2] = 1;
return rVal;
}
}
// public

View File

@ -79,4 +79,29 @@ public class CommonWorldData {
return serverWorldData.convertRealToChunkSpace(real);
}
}
public int getDynamicInterpolationRatio(){
if(clientWorldData != null){
return clientWorldData.getDynamicInterpolationRatio();
} else {
return serverWorldData.getDynamicInterpolationRatio();
}
}
public int getWorldDiscreteSize(){
if(clientWorldData != null){
return clientWorldData.getWorldDiscreteSize();
} else {
return serverWorldData.getWorldSizeDiscrete();
}
}
public float getRandomDampener(){
if(clientWorldData != null){
return clientWorldData.getRandomDampener();
} else {
return serverWorldData.getRandomDampener();
}
}
}

View File

@ -35,8 +35,10 @@ import org.apache.commons.crypto.stream.CryptoOutputStream;
*/
public class ClientNetworking implements Runnable{
String address;
int port;
Socket socket;
public Socket socket;
// CryptoInputStream inputStream;
// CryptoOutputStream outputStream;
InputStream inputStream;
@ -49,27 +51,8 @@ public class ClientNetworking implements Runnable{
static final int MAX_CONNECTION_ATTEMPTS = 10;
public ClientNetworking(String address, int port){
int connectionAttempts = 0;
boolean connected = false;
while(!connected){
try {
this.socket = new Socket(address,port);
} catch (IOException ex) {
LoggerInterface.loggerNetworking.WARNING("Client failed to connect!");
} finally {
connected = true;
}
if(!connected){
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {}
connectionAttempts++;
}
if(connectionAttempts > MAX_CONNECTION_ATTEMPTS){
LoggerInterface.loggerNetworking.ERROR("Max client connection attempts!", new Exception());
System.exit(1);
}
}
this.address = address;
this.port = port;
}
@ -92,14 +75,39 @@ public class ClientNetworking implements Runnable{
// ex.printStackTrace();
// System.exit(1);
// }
//attempt connection
int connectionAttempts = 0;
boolean connected = false;
while(!connected){
try {
this.socket = new Socket(address,port);
connected = true;
} catch (IOException ex) {
LoggerInterface.loggerNetworking.WARNING("Client failed to connect!");
}
if(!connected){
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {}
connectionAttempts++;
}
if(connectionAttempts > MAX_CONNECTION_ATTEMPTS){
LoggerInterface.loggerNetworking.ERROR("Max client connection attempts!", new Exception());
System.exit(1);
}
}
//create parser
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
parser = new NetworkParser(inputStream,outputStream);
} catch (IOException ex) {
Logger.getLogger(ClientNetworking.class.getName()).log(Level.SEVERE, null, ex);
LoggerInterface.loggerNetworking.ERROR("Error on client socket", ex);
}
//start parsing messages
initialized = true;
while(Main.isRunning()){
//attempt poll incoming messages
@ -107,6 +115,7 @@ public class ClientNetworking implements Runnable{
//outgoing messages
parser.pushMessagesOut();
}
}