package electrosphere.engine.loadingthreads; import java.util.Arrays; import java.util.concurrent.TimeUnit; import org.joml.Vector3f; import electrosphere.client.entity.camera.CameraEntityUtils; import electrosphere.client.entity.crosshair.Crosshair; import electrosphere.client.fluid.cells.FluidCellManager; import electrosphere.client.foliagemanager.ClientFoliageManager; import electrosphere.client.sim.ClientSimulation; import electrosphere.client.terrain.cells.DrawCellManager; import electrosphere.client.ui.menu.MenuGenerators; import electrosphere.client.ui.menu.WindowStrings; import electrosphere.client.ui.menu.WindowUtils; import electrosphere.client.ui.menu.mainmenu.MenuGeneratorsMultiplayer; import electrosphere.controls.ControlHandler; import electrosphere.engine.Globals; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.engine.signal.Signal.SignalType; import electrosphere.engine.threads.LabeledThread.ThreadLabel; import electrosphere.entity.DrawableUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityUtils; import electrosphere.logger.LoggerInterface; import electrosphere.net.NetUtils; import electrosphere.net.client.ClientNetworking; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorTextureMask; import electrosphere.renderer.ui.elements.Window; public class ClientLoading { protected static void loadCharacterServer(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); //initialize the client thread (client) initClientThread(); //while we don't know what races are playable, wait while(Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces().size() == 0){ try { TimeUnit.MILLISECONDS.sleep(5); } catch (InterruptedException ex) {} } //once we have them, bring up the character creation interface //init character creation window //eventually should replace with at ui to select an already created character or create a new one WindowUtils.replaceMainMenuContents(MenuGeneratorsMultiplayer.createMultiplayerCharacterCreationWindow()); //make loading dialog disappear loadingWindow.setVisible(false); //make character creation window visible WindowUtils.recursiveSetVisible(Globals.elementService.getWindow(WindowStrings.WINDOW_MENU_MAIN), true); //recapture window Globals.controlHandler.setRecapture(true); //log LoggerInterface.loggerEngine.INFO("[Client]Finished loading character creation menu"); //set menu controls again Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.TITLE_MENU); } protected static void loadClientWorld(Object[] params){ Globals.signalSystem.post(SignalType.UI_MODIFICATION, () -> { WindowUtils.closeWindow(WindowStrings.WINDOW_MENU_MAIN); WindowUtils.recursiveSetVisible(WindowStrings.WINDOW_LOADING, true); }); //disable menu input Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.NO_INPUT); //initialize the "real" objects simulation initClientSimulation(); //init foliage manager initFoliageManager(); //initialize the cell manager (client) initDrawCellManager(true); //init the fluid cell manager initFluidCellManager(true); //initialize the basic graphical entities of the world (skybox, camera) initWorldBaseGraphicalEntities(); //init arena specific stuff (ie different skybox colors) initArenaGraphicalEntities(); //sets micro and macro sims to ready if they exist setSimulationsToReady(); //make loading window disappear Globals.signalSystem.post(SignalType.UI_MODIFICATION, () -> { WindowUtils.recursiveSetVisible(WindowStrings.WINDOW_LOADING, false); 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; }); //recapture screen Globals.controlHandler.setRecapture(true); LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game"); //set controls state Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME); } /** * Loads the viewport */ protected static void loadViewport(Object[] params){ Globals.signalSystem.post(SignalType.UI_MODIFICATION, () -> { WindowUtils.closeWindow(WindowStrings.WINDOW_MENU_MAIN); WindowUtils.recursiveSetVisible(WindowStrings.WINDOW_LOADING, 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)); Globals.cameraHandler.setTrackPlayerEntity(false); Globals.cameraHandler.setUpdate(false); //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 Globals.signalSystem.post(SignalType.UI_MODIFICATION, () -> { WindowUtils.recursiveSetVisible(WindowStrings.WINDOW_LOADING, false); 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; }); //recapture screen Globals.controlHandler.setRecapture(true); LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game"); //set controls state Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME); } /** * Inits the client networking thread and socket */ private static void initClientThread(){ //start client networking if(Globals.RUN_CLIENT){ Globals.clientConnection = new ClientNetworking(NetUtils.getAddress(),NetUtils.getPort()); Globals.threadManager.start(ThreadLabel.NETWORKING_CLIENT, new Thread(Globals.clientConnection)); } } /** * Creates client simulation object */ private static void initClientSimulation(){ if(Globals.clientSimulation == null){ Globals.clientSimulation = new ClientSimulation(); } } /** * Sets client simulation object state to ready */ private static void setSimulationsToReady(){ Globals.clientSimulation.setReady(true); } private static void initWorldBaseGraphicalEntities(){ /* Skybox */ // Model skyboxModel = Globals.assetManager.fetchModel(AssetDataStrings.ASSET_STRING_SKYBOX_BASIC); // Globals.skybox = EntityUtils.spawnDrawableEntity(AssetDataStrings.ASSET_STRING_SKYBOX_BASIC); /* Player Camera */ CameraEntityUtils.initCamera(); /* Targeting crosshair */ Crosshair.initCrossHairEntity(); } static void initArenaGraphicalEntities(){ float skyR = 150; float skyG = 200; float skyB = 250; float groundR = 20; float groundG = 20; float groundB = 20; Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB)); Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB)); Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB)); Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB)); Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB)); Globals.skyboxColors.add(new Vector3f(skyR,skyG,skyB)); Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB)); Globals.skyboxColors.add(new Vector3f(groundR,groundG,groundB)); //starry sky true skybox Entity skybox = EntityCreationUtils.createClientSpatialEntity(); EntityCreationUtils.makeEntityDrawable(skybox, "Models/environment/skyboxSphere.fbx"); DrawableUtils.disableCulling(skybox); EntityUtils.getRotation(skybox).rotateX((float)(-Math.PI/2.0f)); EntityUtils.getScale(skybox).mul(200000.0f); Globals.assetManager.queueOverrideMeshShader("Models/environment/skyboxSphere.fbx", "Sphere", "Shaders/entities/skysphere/skysphere.vs", "Shaders/entities/skysphere/skysphere.fs"); //cloud ring pseudo skybox // Entity cloudRing = EntityCreationUtils.createClientSpatialEntity(); // EntityCreationUtils.makeEntityDrawable(cloudRing, "Models/environment/cloudRing.fbx"); // DrawableUtils.makeEntityTransparent(cloudRing); // DrawableUtils.disableCulling(cloudRing); // EntityUtils.getRotation(cloudRing).rotateX((float)(-Math.PI/2.0f)); // EntityUtils.getScale(cloudRing).mul(100000.0f); // Globals.clientScene.registerBehaviorTree(new ApplyRotationTree(cloudRing,new Quaterniond().rotationZ(0.0001))); // Globals.assetManager.queueOverrideMeshShader("Models/environment/cloudRing.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); //player's cursor Globals.playerCursor = EntityCreationUtils.createClientSpatialEntity(); EntityCreationUtils.makeEntityDrawable(Globals.playerCursor, AssetDataStrings.UNITSPHERE); Actor cursorActor = EntityUtils.getActor(Globals.playerCursor); cursorActor.addTextureMask(new ActorTextureMask("sphere", Arrays.asList(new String[]{"Textures/transparent_red.png"}))); DrawableUtils.makeEntityTransparent(Globals.playerCursor); EntityUtils.getScale(Globals.playerCursor).set(0.2f); } static final int MAX_DRAW_CELL_WAIT = 1000; /** * 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(blockForInit && (Globals.clientWorldData == null || InitialAssetLoading.atlasQueuedTexture == null || !InitialAssetLoading.atlasQueuedTexture.hasLoaded())){ try { TimeUnit.MILLISECONDS.sleep(10); iterations++; } catch (InterruptedException ex) { LoggerInterface.loggerEngine.ERROR(ex); } if(iterations > MAX_DRAW_CELL_WAIT){ String message = "Draw cell took too long to init!\n" + Globals.clientWorldData + "\n" + InitialAssetLoading.atlasQueuedTexture.hasLoaded(); throw new IllegalStateException(message); } } //initialize draw cell manager Globals.drawCellManager = new DrawCellManager(Globals.clientTerrainManager, 0, 0, 0); //construct texture atlas Globals.drawCellManager.attachTextureAtlas(Globals.voxelTextureAtlas); //set our draw cell manager to actually generate drawable chunks Globals.drawCellManager.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(blockForInit && Globals.drawCellManager.containsUnrequestedCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } } while(blockForInit && Globals.drawCellManager.containsUndrawableCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * 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); Globals.fluidCellManager.setGenerateDrawables(true); Globals.clientSimulation.setLoadingTerrain(true); //wait for all the terrain data to arrive while(blockForInit && Globals.fluidCellManager.containsUnrequestedCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } } //wait for undrawable cells while(blockForInit && Globals.fluidCellManager.containsUndrawableCell()){ try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException ex) { ex.printStackTrace(); } } } /** * Starts up the foliage manager */ private static void initFoliageManager(){ Globals.clientFoliageManager = new ClientFoliageManager(); Globals.clientFoliageManager.start(); } }