viewport loading

This commit is contained in:
austin 2024-09-04 00:42:06 -04:00
parent 79629e7524
commit 56b60695c5
19 changed files with 409 additions and 63 deletions

View File

@ -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

View File

@ -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

View File

@ -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){
if(Globals.clientWorldData != null){
worldBoundDiscreteMax = (int)(Globals.clientWorldData.getWorldBoundMin().x / Globals.clientWorldData.getDynamicInterpolationRatio() * 1.0f);
}
cells = new HashSet<FluidCell>();
hasNotRequested = new HashSet<String>();
drawable = new HashSet<String>();

View File

@ -105,16 +105,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
if(Globals.RUN_SIMULATION_ONLY){

View File

@ -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");
}
/**
* Inits the fluid cell manager
* @param blockForInit Blocks the thread until the fluid cell manager is ready
*/
static void initFluidCellManager(boolean blockForInit){
static void initFluidCellManager(){
while(Globals.clientWorldData == null){
//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");
}
}

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -60,6 +60,11 @@ public class LoadingThread extends Thread {
*/
SCRIPT_ENGINE,
/**
* Load viewport
*/
LOAD_VIEWPORT,
}
/**
@ -133,6 +138,11 @@ public class LoadingThread extends Thread {
EngineInitLoading.loadScriptingEngine(this.params);
} break;
//Loads the viewport
case LOAD_VIEWPORT: {
ViewportLoading.loadViewport(this.params);
} break;
}
isDone = true;
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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"));
}
}

View File

@ -82,21 +82,28 @@ public class ServerWorldData {
return rVal;
}
// public static ServerWorldData createGameWorld(ServerTerrainManager terrainManager){
// ServerWorldData rVal = new ServerWorldData();
// rVal.type = WorldType.GAME_WORLD;
/**
* 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;
// rVal.worldMinPoint = new Vector3f(0,0,0);
// int worldDim = terrainManager.getWorldDiscreteSize() * ServerTerrainChunk.CHUNK_DIMENSION;
// rVal.worldMaxPoint = new Vector3f(worldDim,0,worldDim);
//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);
// rVal.dynamicInterpolationRatio = terrainManager.getDynamicInterpolationRatio();
// rVal.worldSizeDiscrete = terrainManager.getWorldDiscreteSize();
// rVal.worldSizeDiscreteVertical = 128;
// rVal.randomDampener = terrainManager.getRandomDampener();
//misc values
rVal.dynamicInterpolationRatio = 1;
rVal.worldSizeDiscrete = 1;
rVal.worldSizeDiscreteVertical = 1;
rVal.randomDampener = ServerTerrainManager.SERVER_TERRAIN_MANAGER_DAMPENER;
// return rVal;
// }
return rVal;
}
/**
* Loads world data from a scene or a save

View File

@ -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;
}
}

View File

@ -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!");

View File

@ -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

View File

@ -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<Player> 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<Player>();
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;
}
}

View File

@ -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();
}
}

View File

@ -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);
//