From 56b60695c549eba8c10cf740f7a37d8799810e94 Mon Sep 17 00:00:00 2001 From: austin Date: Wed, 4 Sep 2024 00:42:06 -0400 Subject: [PATCH] viewport loading --- docs/src/progress/renderertodo.md | 2 + .../auth/AuthenticationManager.java | 25 ++++ .../client/fluid/cells/FluidCellManager.java | 4 +- src/main/java/electrosphere/engine/Main.java | 10 -- .../engine/loadingthreads/ClientLoading.java | 90 +++++++++---- .../loadingthreads/DebugSPWorldLoading.java | 2 +- .../loadingthreads/LevelEditorLoading.java | 2 +- .../engine/loadingthreads/LevelLoading.java | 2 +- .../engine/loadingthreads/LoadingThread.java | 12 +- .../engine/loadingthreads/LoadingUtils.java | 8 +- .../engine/loadingthreads/ServerLoading.java | 2 +- .../loadingthreads/ViewportLoading.java | 83 ++++++++++++ .../game/server/world/ServerWorldData.java | 39 +++--- .../mainmenu/MenuGeneratorsTitleMenu.java | 11 ++ .../net/server/player/PlayerManager.java | 3 + .../server/datacell/RealmManager.java | 27 ++++ .../datacell/ViewportDataCellManager.java | 123 ++++++++++++++++++ .../loadingthreads/ViewportLoadingTests.java | 25 ++++ src/test/java/testutils/EngineInit.java | 2 +- 19 files changed, 409 insertions(+), 63 deletions(-) create mode 100644 src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java create mode 100644 src/main/java/electrosphere/server/datacell/ViewportDataCellManager.java create mode 100644 src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 056daa81..b41d0cc1 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -680,6 +680,8 @@ Server synchronization of sprint tree Fix potential bad path for item state lookup Fix multiple ItemUtils NPE bugs Fix AttachUtils NPE bug +Work on testing stability +Viewport loading # TODO diff --git a/src/main/java/electrosphere/auth/AuthenticationManager.java b/src/main/java/electrosphere/auth/AuthenticationManager.java index 1b19a0df..60ba2309 100644 --- a/src/main/java/electrosphere/auth/AuthenticationManager.java +++ b/src/main/java/electrosphere/auth/AuthenticationManager.java @@ -15,8 +15,33 @@ import electrosphere.server.db.DatabaseResultRow; public class AuthenticationManager { + /** + * Tracks whether this is a mock authentication manager or not + */ + boolean isMock = false; + + /** + * Private constructor + */ + private AuthenticationManager(){ + + } + + /** + * Creates an authentication manager + * @param mock true if this shoud be a mock manager, false for a real one + * @return The authentication manager + */ + public static AuthenticationManager create(boolean mock){ + AuthenticationManager rVal = new AuthenticationManager(); + rVal.isMock = mock; + return rVal; + } public boolean authenticate(String username, String password){ + if(isMock){ + return true; + } //first we hash the input password String hashedPassword = getHashedString(password); //then query the database for the username and hash for the input username diff --git a/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java b/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java index b85be7a1..2224d964 100644 --- a/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java +++ b/src/main/java/electrosphere/client/fluid/cells/FluidCellManager.java @@ -77,7 +77,9 @@ public class FluidCellManager { * @param discreteY The initial discrete position Y coordinate */ public FluidCellManager(ClientTerrainManager clientTerrainManager, int discreteX, int discreteY, int discreteZ){ - worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f); + if(Globals.clientWorldData != null){ + worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f); + } cells = new HashSet(); hasNotRequested = new HashSet(); drawable = new HashSet(); diff --git a/src/main/java/electrosphere/engine/Main.java b/src/main/java/electrosphere/engine/Main.java index ea5d1cd1..506e64b5 100644 --- a/src/main/java/electrosphere/engine/Main.java +++ b/src/main/java/electrosphere/engine/Main.java @@ -104,16 +104,6 @@ public class Main { //init ODE OdeHelper.initODE(); - - // if(1==1){ - // SaveUtils.loadSave("arena"); - // Globals.authenticationManager = new AuthenticationManager(); - // String rawPass = "testpassword"; - // String hashedPassword = AuthenticationManager.getHashedString(rawPass); - // boolean authed = Globals.authenticationManager.authenticate("testuser", hashedPassword); - // System.out.println("Authenticated: " + authed); - // System.exit(0); - // } //world gen testing //gen terrain diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 09523551..12756a5b 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -73,9 +73,9 @@ public class ClientLoading { //init foliage manager initFoliageManager(); //initialize the cell manager (client) - initDrawCellManager(); + initDrawCellManager(true); //init the fluid cell manager - initFluidCellManager(); + initFluidCellManager(true); //initialize the basic graphical entities of the world (skybox, camera) initWorldBaseGraphicalEntities(); //init arena specific stuff (ie different skybox colors) @@ -98,6 +98,45 @@ public class ClientLoading { Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME); } + /** + * Loads the viewport + */ + protected static void loadViewport(Object[] params){ + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + //disable menu input + Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.NO_INPUT); + + //init camera + Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(-1,0,0)); + //initialize the "real" objects simulation + initClientSimulation(); + //init foliage manager + initFoliageManager(); + //initialize the cell managers (client) + initDrawCellManager(false); + initFluidCellManager(false); + + //sets micro and macro sims to ready if they exist + setSimulationsToReady(); + //make loading window disappear + loadingWindow.setVisible(false); + //recapture screen + Globals.controlHandler.setRecapture(true); + //set rendering flags to main game mode + Globals.RENDER_FLAG_RENDER_SHADOW_MAP = true; + Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT = true; + Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER = true; + Globals.RENDER_FLAG_RENDER_UI = true; + Globals.RENDER_FLAG_RENDER_BLACK_BACKGROUND = false; + Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false; + LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game"); + //set controls state + Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME); + } + @@ -207,9 +246,13 @@ public class ClientLoading { static final int MAX_DRAW_CELL_WAIT = 1000; - static void initDrawCellManager(){ + /** + * Inits the drawcell manager + * @param blockForInit Blocks the thread until the draw cell manager is ready + */ + static void initDrawCellManager(boolean blockForInit){ int iterations = 0; - while(Globals.clientWorldData == null || Globals.initialAssetLoadingThread.isLoading()){ + while(blockForInit && (Globals.clientWorldData == null || Globals.initialAssetLoadingThread.isLoading())){ try { TimeUnit.MILLISECONDS.sleep(10); iterations++; @@ -232,67 +275,58 @@ public class ClientLoading { //Alerts the client simulation that it should start loading terrain Globals.clientSimulation.setLoadingTerrain(true); //wait for all the terrain data to arrive - while(Globals.drawCellManager.containsUnrequestedCell()){ -// Globals.drawCellManager.updateInvalidCell(); + while(blockForInit && Globals.drawCellManager.containsUnrequestedCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } -// System.out.println("invalid cell"); } - while(Globals.drawCellManager.containsUndrawableCell()){ -// Globals.drawCellManager.makeCellDrawable(); + while(blockForInit && Globals.drawCellManager.containsUndrawableCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } -// System.out.println("undrawable"); } - - // while(Globals.drawCellManager.containsPhysicsNeedingCell()){ - // try { - // TimeUnit.MILLISECONDS.sleep(10); - // } catch (InterruptedException ex) { - // } - // } - // System.out.println("Draw Cell Manager ready"); } - static void initFluidCellManager(){ - while(Globals.clientWorldData == null){ + /** + * Inits the fluid cell manager + * @param blockForInit Blocks the thread until the fluid cell manager is ready + */ + static void initFluidCellManager(boolean blockForInit){ + + //wait for world data + while(blockForInit && Globals.clientWorldData == null){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { } } + //initialize draw cell manager Globals.fluidCellManager = new FluidCellManager(Globals.clientTerrainManager, 0, 0, 0); - //set our draw cell manager to actually generate drawable chunks Globals.fluidCellManager.setGenerateDrawables(true); - //Alerts the client simulation that it should start loading terrain Globals.clientSimulation.setLoadingTerrain(true); + //wait for all the terrain data to arrive - while(Globals.fluidCellManager.containsUnrequestedCell()){ -// Globals.drawCellManager.updateInvalidCell(); + while(blockForInit && Globals.fluidCellManager.containsUnrequestedCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } -// System.out.println("invalid cell"); } - while(Globals.fluidCellManager.containsUndrawableCell()){ -// Globals.drawCellManager.makeCellDrawable(); + //wait for undrawable cells + while(blockForInit && Globals.fluidCellManager.containsUndrawableCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } -// System.out.println("undrawable"); } } diff --git a/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java b/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java index c18b938b..40c3868a 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/DebugSPWorldLoading.java @@ -40,7 +40,7 @@ public class DebugSPWorldLoading { LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); //init authentication - LoadingUtils.initAuthenticationManager(); + LoadingUtils.initAuthenticationManager(false); //initialize the local connection Globals.clientUsername = "testuser"; Globals.clientPassword = AuthenticationManager.getHashedString("testpass"); diff --git a/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java b/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java index edd388ca..6fba09d5 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LevelEditorLoading.java @@ -68,7 +68,7 @@ public class LevelEditorLoading { LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); //init authentication - LoadingUtils.initAuthenticationManager(); + LoadingUtils.initAuthenticationManager(false); //initialize the local connection Globals.clientUsername = "leveleditor"; Globals.clientPassword = AuthenticationManager.getHashedString("leveleditor"); diff --git a/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java b/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java index 17e02d2e..5a0332e4 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LevelLoading.java @@ -38,7 +38,7 @@ public class LevelLoading { LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); //init authentication - LoadingUtils.initAuthenticationManager(); + LoadingUtils.initAuthenticationManager(false); //initialize the local connection Globals.clientUsername = "leveleditor"; Globals.clientPassword = AuthenticationManager.getHashedString("leveleditor"); diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java index d6de4cb9..2f111286 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingThread.java @@ -60,6 +60,11 @@ public class LoadingThread extends Thread { */ SCRIPT_ENGINE, + /** + * Load viewport + */ + LOAD_VIEWPORT, + } /** @@ -132,7 +137,12 @@ public class LoadingThread extends Thread { case SCRIPT_ENGINE: { EngineInitLoading.loadScriptingEngine(this.params); } break; - + + //Loads the viewport + case LOAD_VIEWPORT: { + ViewportLoading.loadViewport(this.params); + } break; + } isDone = true; } diff --git a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java index 7243e382..908ae35c 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java +++ b/src/main/java/electrosphere/engine/loadingthreads/LoadingUtils.java @@ -71,9 +71,13 @@ public class LoadingUtils { } } - static void initAuthenticationManager(){ + /** + * Initializes the authentication manager + * @param mock true if it should make a mock authentication manager, false for a real auth manager + */ + static void initAuthenticationManager(boolean mock){ if(Globals.RUN_SERVER){ - Globals.authenticationManager = new AuthenticationManager(); + Globals.authenticationManager = AuthenticationManager.create(mock); } } diff --git a/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java index 122613ba..ba7860b2 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ServerLoading.java @@ -25,7 +25,7 @@ public class ServerLoading { // Globals.dataCellManager = new DataCellManager(Globals.serverWorldData); LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); //init authentication - LoadingUtils.initAuthenticationManager(); + LoadingUtils.initAuthenticationManager(false); //initialize the server thread (server only) LoadingUtils.initServerThread(); //initialize the "virtual" objects simulation diff --git a/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java new file mode 100644 index 00000000..d7a23f5d --- /dev/null +++ b/src/main/java/electrosphere/engine/loadingthreads/ViewportLoading.java @@ -0,0 +1,83 @@ +package electrosphere.engine.loadingthreads; + +import java.util.concurrent.TimeUnit; + +import org.joml.Vector3d; + +import electrosphere.auth.AuthenticationManager; +import electrosphere.engine.Globals; +import electrosphere.entity.types.creature.CreatureTemplate; +import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.logger.LoggerInterface; +import electrosphere.menu.MenuGenerators; +import electrosphere.menu.WindowStrings; +import electrosphere.menu.WindowUtils; +import electrosphere.net.parser.net.message.TerrainMessage; +import electrosphere.net.server.player.Player; +import electrosphere.renderer.ui.elements.Window; +import electrosphere.server.db.DatabaseController; + +/** + * Loads the viewport + */ +public class ViewportLoading { + + /** + * Loads the viewport + */ + protected static void loadViewport(Object[] params){ + // + //show loading + Window loadingWindow = (Window)Globals.elementService.getWindow(WindowStrings.WINDOW_LOADING); + WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), false); + WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu()); + loadingWindow.setVisible(true); + + // + //init realm manager with viewport realm + Globals.realmManager.createViewportRealm(new Vector3d(0,0,0), new Vector3d(16,16,16)); + + // + //connect client to server + LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); + Globals.dbController = new DatabaseController(); + LoadingUtils.initAuthenticationManager(true); + Globals.clientUsername = "leveleditor"; + Globals.clientPassword = AuthenticationManager.getHashedString("leveleditor"); + LoadingUtils.initLocalConnection(true); + //wait for player object creation + while(Globals.playerManager.getPlayers().size() < 1){ + try { + TimeUnit.MILLISECONDS.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + //add player to viewport realm + Player localPlayer = Globals.playerManager.getFirstPlayer(); + Globals.realmManager.first().getDataCellManager().addPlayerToRealm(localPlayer); + + //initialize the "real" objects simulation + LoadingUtils.initMicroSimulation(); + LoadingUtils.setSimulationsToReady(); + LoggerInterface.loggerEngine.INFO("[Server]Finished loading level editor"); + + //request terrain data + Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestMetadataMessage()); + + //block for client world data + while(Globals.clientWorldData == null){ + try { + TimeUnit.MILLISECONDS.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + //Run client startup process + ClientLoading.loadViewport(params); + + CreatureUtils.serverSpawnBasicCreature(Globals.realmManager.first(), new Vector3d(1,1,1), "human", CreatureTemplate.createDefault("human")); + } + +} diff --git a/src/main/java/electrosphere/game/server/world/ServerWorldData.java b/src/main/java/electrosphere/game/server/world/ServerWorldData.java index 03bd04b4..f4bc03f3 100644 --- a/src/main/java/electrosphere/game/server/world/ServerWorldData.java +++ b/src/main/java/electrosphere/game/server/world/ServerWorldData.java @@ -81,22 +81,29 @@ public class ServerWorldData { return rVal; } - - // public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){ - // ServerWorldData rVal = new ServerWorldData(); - // rVal.type = WorldType.GAME_WORLD; - - // rVal.worldMinPoint = new Vector3f(0,0,0); - // int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION; - // rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim); - - // rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio(); - // rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize(); - // rVal.worldSizeDiscreteVertical = 128; - // rVal.randomDampener = terrainManager.getRandomDampener(); - - // return rVal; - // } + + /** + * Creates a server world data object with a fixed size + * @param minPoint The minimum point of the world + * @param maxPoint The maximum point of the world + * @return The server world data object + */ + public static ServerWorldData createFixedWorldData(Vector3d minPoint, Vector3d maxPoint){ + ServerWorldData rVal = new ServerWorldData(); + rVal.type = WorldType.LEVEL; + + //min and max real points + rVal.worldMinPoint = new Vector3f((float)minPoint.x,(float)minPoint.y,(float)minPoint.z); + rVal.worldMaxPoint = new Vector3f((float)maxPoint.x,(float)maxPoint.y,(float)maxPoint.z); + + //misc values + rVal.dynamicInterpolationRatio = 1; + rVal.worldSizeDiscrete = 1; + rVal.worldSizeDiscreteVertical = 1; + rVal.randomDampener = ServerTerrainManager.SERVER_TERRAIN_MANAGER_DAMPENER; + + return rVal; + } /** * Loads world data from a scene or a save diff --git a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java index aea394f3..dc4e1fb5 100644 --- a/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java +++ b/src/main/java/electrosphere/menu/mainmenu/MenuGeneratorsTitleMenu.java @@ -106,6 +106,17 @@ public class MenuGeneratorsTitleMenu { return false; }}); + //button (Viewport Test) + Button viewportTestingButton = new Button(); + Label viewportTestingLabel = new Label(1.0f); + viewportTestingLabel.setText("Viewport Test"); + viewportTestingButton.addChild(viewportTestingLabel); + rVal.addChild(viewportTestingButton); + viewportTestingButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){ + Globals.threadManager.start(new LoadingThread(LoadingThreadType.LOAD_VIEWPORT)); + return false; + }}); + return rVal; } } diff --git a/src/main/java/electrosphere/net/server/player/PlayerManager.java b/src/main/java/electrosphere/net/server/player/PlayerManager.java index b64718b3..e62f4082 100644 --- a/src/main/java/electrosphere/net/server/player/PlayerManager.java +++ b/src/main/java/electrosphere/net/server/player/PlayerManager.java @@ -49,6 +49,9 @@ public class PlayerManager { * @return The realm if it exists, null otherwise */ public Realm getPlayerRealm(Player player){ + if(Globals.realmManager.getRealms().size() == 1){ + return Globals.realmManager.first(); + } Entity playerEntity = player.getPlayerEntity(); if(playerEntity == null){ throw new IllegalStateException("Trying to get realm of player who does not have an entity assigned!"); diff --git a/src/main/java/electrosphere/server/datacell/RealmManager.java b/src/main/java/electrosphere/server/datacell/RealmManager.java index 295de9e2..afd593f7 100644 --- a/src/main/java/electrosphere/server/datacell/RealmManager.java +++ b/src/main/java/electrosphere/server/datacell/RealmManager.java @@ -5,6 +5,8 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; +import org.joml.Vector3d; + import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionWorldData; import electrosphere.collision.hitbox.HitboxManager; @@ -63,6 +65,31 @@ public class RealmManager { return realm; } + /** + * Creates a viewport realm + * @return The viewport realm + */ + public Realm createViewportRealm(Vector3d minPoint, Vector3d maxPoint){ + //create the server world data + ServerWorldData serverWorldData = ServerWorldData.createFixedWorldData(minPoint, maxPoint); + + //create collision engine + CollisionEngine collisionEngine = new CollisionEngine(); + collisionEngine.setCollisionWorldData(new CollisionWorldData(serverWorldData)); + + //create realm + Realm realm = new Realm(serverWorldData, collisionEngine, new HitboxManager(new ServerHitboxResolutionCallback()), ServerContentManager.createServerContentManager(false)); + + //add function classes to realm + realm.setDataCellManager(ViewportDataCellManager.create(realm)); + realm.setEntityDataCellMapper(new EntityDataCellMapper()); + + //register + realms.add(realm); + + return realm; + } + /** * Maps an entity to a realm * @param entity The entity diff --git a/src/main/java/electrosphere/server/datacell/ViewportDataCellManager.java b/src/main/java/electrosphere/server/datacell/ViewportDataCellManager.java new file mode 100644 index 00000000..497ba07a --- /dev/null +++ b/src/main/java/electrosphere/server/datacell/ViewportDataCellManager.java @@ -0,0 +1,123 @@ +package electrosphere.server.datacell; + +import java.util.LinkedList; +import java.util.List; + +import org.joml.Vector3d; +import org.joml.Vector3i; + +import electrosphere.engine.Globals; +import electrosphere.entity.Scene; +import electrosphere.net.server.player.Player; +import electrosphere.server.datacell.interfaces.DataCellManager; + +public class ViewportDataCellManager implements DataCellManager { + + /** + * The players in the realm + */ + List players; + + /** + * The data cell for the realm + */ + ServerDataCell serverDataCell; + + /** + * The parent realm + */ + Realm parent; + + /** + * Creates a viewport data cell manager + * @param realm The realm that will be parent to this manager + * @return The viewport data cell manager + */ + public static ViewportDataCellManager create(Realm realm){ + ViewportDataCellManager rVal = new ViewportDataCellManager(); + rVal.players = new LinkedList(); + rVal.serverDataCell = new ServerDataCell(new Scene()); + rVal.parent = realm; + return rVal; + } + + @Override + public void addPlayerToRealm(Player player) { + players.add(player); + this.serverDataCell.addPlayer(player); + } + + @Override + public void movePlayer(Player player, Vector3i newPosition) { + //do nothing, only one data cell in the viewport manager + } + + @Override + public boolean updatePlayerPositions() { + //never moves to another cell + return false; + } + + @Override + public ServerDataCell getDataCellAtPoint(Vector3d point) { + return serverDataCell; + } + + @Override + public Vector3i getCellWorldPosition(ServerDataCell cell) { + return new Vector3i(0,0,0); + } + + @Override + public ServerDataCell tryCreateCellAtPoint(Vector3d point) { + return serverDataCell; + } + + @Override + public ServerDataCell getCellAtWorldPosition(Vector3i position) { + return serverDataCell; + } + + @Override + public void simulate() { + if(Globals.microSimulation != null && Globals.microSimulation.isReady()){ + Globals.microSimulation.simulate(this.serverDataCell); + } + updatePlayerPositions(); + } + + @Override + public void unloadPlayerlessChunks() { + //does nothing + } + + @Override + public void save(String saveName) { + //does nothing + } + + @Override + public Vector3d guaranteePositionIsInBounds(Vector3d positionToTest) { + Vector3d returnPos = new Vector3d(positionToTest); + if(positionToTest.x < parent.getServerWorldData().getWorldBoundMin().x){ + returnPos.x = parent.getServerWorldData().getWorldBoundMin().x + 1; + } + if(positionToTest.x >= parent.getServerWorldData().getWorldBoundMax().x){ + returnPos.x = parent.getServerWorldData().getWorldBoundMax().x - 1; + } + if(positionToTest.y < parent.getServerWorldData().getWorldBoundMin().y){ + returnPos.y = parent.getServerWorldData().getWorldBoundMin().y + 1; + } + if(positionToTest.y >= parent.getServerWorldData().getWorldBoundMax().y){ + returnPos.y = parent.getServerWorldData().getWorldBoundMax().y - 1; + } + if(positionToTest.z < parent.getServerWorldData().getWorldBoundMin().z){ + returnPos.z = parent.getServerWorldData().getWorldBoundMin().z + 1; + } + if(positionToTest.z >= parent.getServerWorldData().getWorldBoundMax().z){ + returnPos.z = parent.getServerWorldData().getWorldBoundMax().z - 1; + } + return returnPos; + } + +} diff --git a/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java b/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java new file mode 100644 index 00000000..2f934f7d --- /dev/null +++ b/src/test/java/electrosphere/engine/loadingthreads/ViewportLoadingTests.java @@ -0,0 +1,25 @@ +package electrosphere.engine.loadingthreads; + +import annotations.IntegrationTest; +import electrosphere.engine.Main; +import testutils.EngineInit; +import testutils.TestEngineUtils; + +/** + * Tests loading viewport + */ +public class ViewportLoadingTests { + + @IntegrationTest + public void testViewportLoading(){ + //init engine + TestEngineUtils.initGraphicalEngine(); + + //load scene + EngineInit.setupConnectedTestScene(); + + //shutdown engine + Main.shutdown(); + } + +} diff --git a/src/test/java/testutils/EngineInit.java b/src/test/java/testutils/EngineInit.java index 42ea2a3e..94a5ebe7 100644 --- a/src/test/java/testutils/EngineInit.java +++ b/src/test/java/testutils/EngineInit.java @@ -17,7 +17,7 @@ public class EngineInit { public static void setupConnectedTestScene(){ // //load the scene - LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LEVEL,"testscene1"); + LoadingThread loadingThread = new LoadingThread(LoadingThreadType.LOAD_VIEWPORT); Globals.threadManager.start(loadingThread); //