diff --git a/src/main/java/electrosphere/entity/EntityManager.java b/src/main/java/electrosphere/entity/EntityManager.java index b056f261..5d42944d 100644 --- a/src/main/java/electrosphere/entity/EntityManager.java +++ b/src/main/java/electrosphere/entity/EntityManager.java @@ -208,29 +208,36 @@ public class EntityManager { } public void clearOutOfBoundsEntities(){ - for(Entity entity : entityList){ - if(entity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) || entity.getDataKeys().contains(EntityDataStrings.ATTACH_PARENT) || entity.getDataKeys().contains(EntityDataStrings.COLLISION_ENTITY_PARENT)){ - - } else { - Vector3f position = EntityUtils.getPosition(entity); - //common world data is initialized with the collision data - //if this is null then the engine hasn't fully started up yet - if(Globals.commonWorldData != null && position != null){ - int worldX = Globals.commonWorldData.convertRealToWorld(position.x); - int worldY = Globals.commonWorldData.convertRealToWorld(position.z); - if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldY)){ - //if we're running the server we need to just hide the entity - //otherwise delete it - if(Globals.RUN_SERVER && Globals.RUN_CLIENT){ - recursiveHide(entity); - } else { - recursiveDeregister(entity); - } + if(Globals.commonWorldData != null && Globals.playerCharacter != null && Globals.clientPlayerData != null){ + Vector3f playerCharacterPos = EntityUtils.getPosition(Globals.playerCharacter); + int playerCharacterWorldX = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.x); + int playerCharacterWorldY = Globals.commonWorldData.convertRealToWorld(playerCharacterPos.z); + if(playerCharacterWorldX != Globals.clientPlayerData.getWorldPositionX() || playerCharacterWorldY != Globals.clientPlayerData.getWorldPositionY()){ + for(Entity entity : entityList){ + if(entity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) || entity.getDataKeys().contains(EntityDataStrings.ATTACH_PARENT) || entity.getDataKeys().contains(EntityDataStrings.COLLISION_ENTITY_PARENT)){ + } else { - //if the entity is within range, we're running server, - //and it's not set to visible, make it visible - if(Globals.RUN_SERVER && Globals.RUN_CLIENT){ - recursiveShow(entity); + Vector3f position = EntityUtils.getPosition(entity); + //common world data is initialized with the collision data + //if this is null then the engine hasn't fully started up yet + if(position != null){ + int worldX = Globals.commonWorldData.convertRealToWorld(position.x); + int worldY = Globals.commonWorldData.convertRealToWorld(position.z); + if(!Globals.drawCellManager.coordsInPhysicsSpace(worldX, worldY)){ + //if we're running the server we need to just hide the entity + //otherwise delete it + if(Globals.RUN_SERVER && Globals.RUN_CLIENT){ + recursiveHide(entity); + } else { + recursiveDeregister(entity); + } + } else { + //if the entity is within range, we're running server, + //and it's not set to visible, make it visible + if(Globals.RUN_SERVER && Globals.RUN_CLIENT){ + recursiveShow(entity); + } + } } } } diff --git a/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java b/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java index dc455ee7..ca1b69d7 100644 --- a/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java +++ b/src/main/java/electrosphere/game/server/world/datacell/DataCellManager.java @@ -110,7 +110,8 @@ public class DataCellManager { throw new UnsupportedOperationException("Removing players from the data cell manager isn't supported -- DataCellManager -- removePlayer(Player player)"); } - public void updatePlayerPositions(){ + public boolean updatePlayerPositions(){ + boolean playerChangedChunk = false; for(Player player : playerList){ Entity playerEntity = player.getPlayerEntity(); if(playerEntity != null){ @@ -119,9 +120,11 @@ public class DataCellManager { int currentWorldY = Globals.serverWorldData.convertRealToChunkSpace(position.z); if(currentWorldX != player.getWorldX() || currentWorldY != player.getWorldY()){ movePlayer(player,currentWorldX,currentWorldY); + playerChangedChunk = true; } } } + return playerChangedChunk; } public void sendNetworkMessageToChunk(NetworkMessage message, int worldX, int worldY){ diff --git a/src/main/java/electrosphere/game/state/MicroSimulation.java b/src/main/java/electrosphere/game/state/MicroSimulation.java index 19872d52..3eec2cf1 100644 --- a/src/main/java/electrosphere/game/state/MicroSimulation.java +++ b/src/main/java/electrosphere/game/state/MicroSimulation.java @@ -18,6 +18,7 @@ import electrosphere.entity.types.particle.ParticleUtils; import electrosphere.main.Globals; import static electrosphere.main.Main.deltaTime; import electrosphere.renderer.Actor; +import org.joml.Vector3f; /** * @@ -104,8 +105,10 @@ public class MicroSimulation { } //data cell manager update if(Globals.dataCellManager != null){ - Globals.dataCellManager.updatePlayerPositions(); - Globals.dataCellManager.unloadPlayerlessChunks(); + boolean playerHasChangedChunk = Globals.dataCellManager.updatePlayerPositions(); + if(playerHasChangedChunk){ + Globals.dataCellManager.unloadPlayerlessChunks(); + } } } diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index 9bbdacaf..c4e49b8f 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -191,14 +191,19 @@ public class Main { } ClientFunctions.runClientFunctions(); + // + // P L A Y E R W O R L D P O S I T I O N U P D A T E + // + if(Globals.playerCharacter != null && Globals.commonWorldData != null){ + newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerCharacter); + Globals.clientPlayerData.setWorldPosition(Globals.commonWorldData.convertRealToWorld(newPlayerCharacterPosition.x), Globals.commonWorldData.convertRealToWorld(newPlayerCharacterPosition.z)); + } /// /// C L I E N T C E L L M A N A G E R /// if(Globals.drawCellManager != null){ - if(Globals.playerCharacter != null){ - newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerCharacter); - } + //Cell manager do your things Globals.drawCellManager.calculateDeltas(oldPlayerCharacterPosition, newPlayerCharacterPosition); Globals.drawCellManager.update(); diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index f44f290d..7810a2cf 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -20,6 +20,7 @@ import electrosphere.renderer.ui.Widget; import org.joml.Matrix4f; import org.joml.Quaternionf; import org.joml.Vector3f; +import org.lwjgl.glfw.GLFW; import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR; import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR; import static org.lwjgl.glfw.GLFW.GLFW_CURSOR; @@ -84,6 +85,8 @@ public class RenderingEngine { public static boolean renderHitboxes = false; public static boolean renderPhysics = false; + static float currentViewPlanarAngle; + ShaderProgram activeProgram; @@ -117,6 +120,10 @@ public class RenderingEngine { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //this disables vsync to make game run faster + //https://stackoverflow.com/questions/55598376/glfwswapbuffers-is-slow + GLFW.glfwSwapInterval(0); + // //Hide the cursor and capture it // glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); @@ -150,9 +157,46 @@ public class RenderingEngine { Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f)); } + static float calculateAngle(Vector3f origin, Vector3f target){ + float rVal = (float)Math.atan2(target.z - origin.z, target.x - origin.x); + if(rVal < 0){ + rVal = rVal + (float)(Math.PI * 2); + } + return rVal; + } + + static float calculateDist(Vector3f origin, Vector3f target){ + return origin.distance(target); + } + + + static boolean drawPoint(Vector3f cameraPos, Vector3f position){ + boolean rVal = true; + float phi = (float)Math.abs((calculateAngle(cameraPos,position) - currentViewPlanarAngle) % (Math.PI * 2.0f)); + if(phi > Math.PI){ + phi = (float)(Math.PI * 2) - phi; + } + float rotationalDiff = phi; + float dist = calculateDist(new Vector3f(cameraPos.x,0,cameraPos.z), new Vector3f(position.x,0,position.z)); + if(rotationalDiff > (Globals.FOV / 180 * Math.PI) && dist > 300){ + rVal = false; + } + return rVal; + } + + void calculateRenderingAngle(){ + currentViewPlanarAngle = calculateAngle(CameraEntityUtils.getCameraEye(Globals.playerCamera), new Vector3f(0,0,0)); +// System.out.println(currentViewPlanarAngle); + } + public void drawScreen(){ + //calculate render angle for frustum culling + if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ + calculateRenderingAngle(); + } + // //first pass: generate depth map // @@ -243,9 +287,11 @@ public class RenderingEngine { // // D R A W A L L E N T I T I E S // + Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); modelTransformMatrix = new Matrix4f(); for(Entity currentEntity : Globals.entityManager.getDrawable()){ - if((boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ + Vector3f position = EntityUtils.getPosition(currentEntity); + if((boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && drawPoint(cameraPos,position)){ //fetch actor Actor currentActor = EntityUtils.getActor(currentEntity); //calculate and apply model transform @@ -292,9 +338,11 @@ public class RenderingEngine { // // D R A W A L L E N T I T I E S // + Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); modelTransformMatrix = new Matrix4f(); for(Entity currentEntity : Globals.entityManager.getDrawable()){ - if((boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW)){ + Vector3f position = EntityUtils.getPosition(currentEntity); + if((boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && drawPoint(cameraPos,position)){ //fetch actor Actor currentActor = EntityUtils.getActor(currentEntity); currentActor.incrementAnimationTime(0.001);