variable size for block editing
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
7b1610d847
commit
f7c6208a2a
@ -1535,6 +1535,7 @@ Fix macro character entities not being assigned ServerCharacterData
|
||||
Audio on placing blocks
|
||||
Audio on placing/removing voxels
|
||||
Debounce item usage activations
|
||||
Variable block editing size
|
||||
|
||||
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ import org.joml.Vector3d;
|
||||
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.script.ClientScriptUtils;
|
||||
import electrosphere.client.terrain.editing.BlockEditing;
|
||||
import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
@ -148,16 +149,12 @@ public class ItemActions {
|
||||
if(cursorPos == null){
|
||||
cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).normalize().mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE));
|
||||
}
|
||||
//tell the server we want the secondary hand item to START doing something
|
||||
Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage(
|
||||
"handRight",
|
||||
ITEM_ACTION_CODE_SECONDARY,
|
||||
ITEM_ACTION_CODE_STATE_ON,
|
||||
cursorPos.x,
|
||||
cursorPos.y,
|
||||
cursorPos.z
|
||||
));
|
||||
//TODO: do any immediate client side calculations here (ie start playing an animation until we get response from server)
|
||||
|
||||
//send server message if we're not doing a block edit
|
||||
//client sends custom packets for block editing
|
||||
boolean sendServerMessage = true;
|
||||
|
||||
//do any immediate client side calculations here (ie start playing an animation until we get response from server)
|
||||
if(Globals.playerEntity != null){
|
||||
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
|
||||
Entity primaryEntity = clientToolbarState.getCurrentPrimaryItem();
|
||||
@ -168,11 +165,25 @@ public class ItemActions {
|
||||
}
|
||||
if(data.getSecondaryUsage() != null){
|
||||
if(data.getSecondaryUsage().getBlockId() != null){
|
||||
sendServerMessage = false;
|
||||
BlockEditing.editBlock((short)(int)data.getSecondaryUsage().getBlockId(),(short)0);
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(AssetDataStrings.INTERACT_SFX_BLOCK_PLACE, VirtualAudioSourceType.CREATURE, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//send server message
|
||||
if(sendServerMessage){
|
||||
//tell the server we want the secondary hand item to START doing something
|
||||
Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage(
|
||||
"handRight",
|
||||
ITEM_ACTION_CODE_SECONDARY,
|
||||
ITEM_ACTION_CODE_STATE_ON,
|
||||
cursorPos.x,
|
||||
cursorPos.y,
|
||||
cursorPos.z
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -4,6 +4,7 @@ import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
@ -178,17 +179,39 @@ public class ClientWorldData {
|
||||
*/
|
||||
public Vector3d convertWorldToRealSpace(Vector3i position){
|
||||
return new Vector3d(
|
||||
convertWorldToReal(position.x),
|
||||
convertWorldToReal(position.y),
|
||||
convertWorldToReal(position.z)
|
||||
this.convertWorldToReal(position.x),
|
||||
this.convertWorldToReal(position.y),
|
||||
this.convertWorldToReal(position.z)
|
||||
);
|
||||
}
|
||||
|
||||
public Vector3i convertRealToVoxelSpace(Vector3d position){
|
||||
return new Vector3i(
|
||||
(int)Math.floor(position.x - convertChunkToRealSpace(convertRealToChunkSpace(position.x))),
|
||||
(int)Math.floor(position.y - convertChunkToRealSpace(convertRealToChunkSpace(position.y))),
|
||||
(int)Math.floor(position.z - convertChunkToRealSpace(convertRealToChunkSpace(position.z)))
|
||||
(int)Math.floor(position.x - this.convertChunkToRealSpace(this.convertRealToChunkSpace(position.x))),
|
||||
(int)Math.floor(position.y - this.convertChunkToRealSpace(this.convertRealToChunkSpace(position.y))),
|
||||
(int)Math.floor(position.z - this.convertChunkToRealSpace(this.convertRealToChunkSpace(position.z)))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a real position to a block position
|
||||
* @param real The real position
|
||||
* @return The closest block position
|
||||
*/
|
||||
public int convertRealToLocalBlockSpace(double real){
|
||||
return (int)Math.floor(real * BlockChunkData.BLOCKS_PER_UNIT_DISTANCE % BlockChunkData.CHUNK_DATA_WIDTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the position to a block-space position
|
||||
* @param position The real-space position
|
||||
* @return The nearest block-space position
|
||||
*/
|
||||
public Vector3i convertRealToBlockSpace(Vector3d position){
|
||||
return new Vector3i(
|
||||
this.convertRealToLocalBlockSpace(position.x),
|
||||
this.convertRealToLocalBlockSpace(position.y),
|
||||
this.convertRealToLocalBlockSpace(position.z)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
/**
|
||||
@ -116,4 +117,21 @@ public class ScriptClientVoxelUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a block edit from the client
|
||||
* @param chunkPos The position of the chunk to edit
|
||||
* @param blockPos The position of the block to edit
|
||||
* @param blockType The type of block
|
||||
* @param blockMetadata The metadata of the block
|
||||
* @param size The size of the blocks to edit
|
||||
*/
|
||||
@Export
|
||||
public static void clientRequestEditBlock(Vector3i chunkPos, Vector3i blockPos, short blockType, short blockMetadata, int size){
|
||||
Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestEditBlockMessage(
|
||||
chunkPos.x, chunkPos.y, chunkPos.z,
|
||||
blockPos.x, blockPos.y, blockPos.z,
|
||||
blockType, blockMetadata, size
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package electrosphere.client.terrain.editing;
|
||||
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.script.ScriptClientVoxelUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* Utilities for editing blocks
|
||||
*/
|
||||
public class BlockEditing {
|
||||
|
||||
/**
|
||||
* Edit blocks
|
||||
* @param type The type of block
|
||||
* @param metadata The metadata of the block
|
||||
*/
|
||||
public static void editBlock(short type, short metadata){
|
||||
Vector3i cornerVoxel = Globals.cursorState.getBlockCornerVoxelPos();
|
||||
int blockSize = Globals.cursorState.getBlockSize();
|
||||
Vector3i chunkPos = Globals.clientWorldData.convertRealToWorldSpace(EntityUtils.getPosition(Globals.playerBlockCursor));
|
||||
ScriptClientVoxelUtils.clientRequestEditBlock(chunkPos, cornerVoxel, type, metadata, blockSize);
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,9 +5,7 @@ import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.entity.crosshair.Crosshair;
|
||||
import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.renderer.ui.events.MouseEvent;
|
||||
@ -18,29 +16,59 @@ import electrosphere.util.math.SpatialMathUtils;
|
||||
*/
|
||||
public class CameraHandler {
|
||||
|
||||
//The first person camera perspective
|
||||
/**
|
||||
* The first person camera perspective
|
||||
*/
|
||||
public static final int CAMERA_PERSPECTIVE_FIRST = 1;
|
||||
//The third person camera perspective
|
||||
|
||||
/**
|
||||
* The third person camera perspective
|
||||
*/
|
||||
public static final int CAMERA_PERSPECTIVE_THIRD = 3;
|
||||
|
||||
//the horizontal mouse sensitivity
|
||||
/**
|
||||
* the horizontal mouse sensitivity
|
||||
*/
|
||||
float mouseSensitivityHorizontal = .1f;
|
||||
//the vertical mouse sensitivity
|
||||
|
||||
/**
|
||||
* the vertical mouse sensitivity
|
||||
*/
|
||||
float mouseSensitivityVertical = .08f;
|
||||
//the speed of the freecam
|
||||
|
||||
/**
|
||||
* the speed of the freecam
|
||||
*/
|
||||
float cameraSpeed;
|
||||
//the current yaw
|
||||
|
||||
/**
|
||||
* the current yaw
|
||||
*/
|
||||
float yaw = 150;
|
||||
//the current pitch
|
||||
|
||||
/**
|
||||
* the current pitch
|
||||
*/
|
||||
float pitch = 50;
|
||||
//the camera's rotation vector
|
||||
|
||||
/**
|
||||
* the camera's rotation vector
|
||||
*/
|
||||
Vector3d cameraRotationVector = new Vector3d();
|
||||
//the radial offset of the camera
|
||||
|
||||
/**
|
||||
* the radial offset of the camera
|
||||
*/
|
||||
Vector3d radialOffset = new Vector3d(0,1,0);
|
||||
//if set to true, the camera will track the player's entity
|
||||
|
||||
/**
|
||||
* if set to true, the camera will track the player's entity
|
||||
*/
|
||||
boolean trackPlayerEntity = true;
|
||||
|
||||
//sets whether the camera handler should update the player's camera or not
|
||||
/**
|
||||
* sets whether the camera handler should update the player's camera or not
|
||||
*/
|
||||
boolean update = true;
|
||||
|
||||
/**
|
||||
@ -138,37 +166,12 @@ public class CameraHandler {
|
||||
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
||||
|
||||
//update the cursor on client side
|
||||
this.updatePlayerCursor();
|
||||
Globals.cursorState.updatePlayerCursor();
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the position of the player's in world cursor
|
||||
*/
|
||||
private void updatePlayerCursor(){
|
||||
CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine();
|
||||
Entity camera = Globals.playerCamera;
|
||||
if(
|
||||
collisionEngine != null &&
|
||||
camera != null &&
|
||||
Globals.playerCursor != null
|
||||
){
|
||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||
Vector3d cursorPos = collisionEngine.rayCastPosition(centerPos, new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||
if(cursorPos == null){
|
||||
cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).normalize().mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE));
|
||||
}
|
||||
EntityUtils.getPosition(Globals.playerCursor).set(cursorPos);
|
||||
|
||||
//clamp block cursor to nearest voxel
|
||||
cursorPos.set(PlayerCursor.clampPositionToNearestBlock(cursorPos));
|
||||
EntityUtils.getPosition(Globals.playerBlockCursor).set(cursorPos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the yaw of the camera handler
|
||||
* @return the yaw
|
||||
|
||||
@ -5,15 +5,23 @@ import org.lwjgl.glfw.GLFWKeyCallbackI;
|
||||
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
/**
|
||||
* Callback that is invoked on key input received by GLFW
|
||||
*/
|
||||
public class ControlCallback implements GLFWKeyCallbackI {
|
||||
|
||||
/**
|
||||
* The size of the key state tracking array
|
||||
*/
|
||||
static final short KEY_VALUE_ARRAY_SIZE = 512;
|
||||
|
||||
/**
|
||||
* Array that tracks the state of keys
|
||||
*/
|
||||
boolean[] keyValues = new boolean[KEY_VALUE_ARRAY_SIZE];
|
||||
|
||||
@Override
|
||||
public void invoke(long window, int key, int scancode, int action, int mods) {
|
||||
|
||||
public void invoke(long window, int key, int scancode, int action, int mods){
|
||||
if(key >= 0 && key < KEY_VALUE_ARRAY_SIZE){
|
||||
if(action == GLFW.GLFW_PRESS || action == GLFW.GLFW_REPEAT){
|
||||
keyValues[key] = true;
|
||||
@ -21,18 +29,12 @@ public class ControlCallback implements GLFWKeyCallbackI {
|
||||
keyValues[key] = false;
|
||||
}
|
||||
}
|
||||
// if(key == GLFW.GLFW_KEY_D){
|
||||
// System.out.println("[D]Action: " + action + " keyValues: " + keyValues[key]);
|
||||
// }
|
||||
// if(key == GLFW.GLFW_KEY_W){
|
||||
// System.out.println("[W]Action: " + action + " keyValues: " + keyValues[key]);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* !!!WARNING!!!, will silently fail if opengl elementsn ot defined or keycode is outside of key value array size or is not in main rendering thread
|
||||
* @param keycode
|
||||
* @return
|
||||
* @param keycode The keycode to check
|
||||
* @return true if it is pressed, false otherwise
|
||||
*/
|
||||
public boolean getKey(int keycode){
|
||||
if(keycode >= 0 && keycode < KEY_VALUE_ARRAY_SIZE){
|
||||
|
||||
@ -116,7 +116,7 @@ public class ControlHandler {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
ControlHandler(){
|
||||
private ControlHandler(){
|
||||
controls = new HashMap<String, Control>();
|
||||
}
|
||||
|
||||
@ -375,25 +375,25 @@ public class ControlHandler {
|
||||
}
|
||||
|
||||
//set to menu state if a menu is open, otherwise use the hinted control scheme
|
||||
if(onlyInventoryMenusOpen()){
|
||||
setHandlerState(ControlsState.INVENTORY);
|
||||
} else if(hasControlBlockingMenuOpen()){
|
||||
setHandlerState(ControlsState.IN_GAME_MAIN_MENU);
|
||||
if(this.onlyInventoryMenusOpen()){
|
||||
this.setHandlerState(ControlsState.INVENTORY);
|
||||
} else if(this.hasControlBlockingMenuOpen()){
|
||||
this.setHandlerState(ControlsState.IN_GAME_MAIN_MENU);
|
||||
} else {
|
||||
setHandlerState(properState);
|
||||
this.setHandlerState(properState);
|
||||
}
|
||||
//checks if the current handler state should have mouse enabled or not
|
||||
if(Arrays.binarySearch(mouseEnabledStates,getHandlerState()) >= 0){
|
||||
showMouse();
|
||||
this.showMouse();
|
||||
} else {
|
||||
hideMouse();
|
||||
this.hideMouse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the mouse position from the glfw buffer to variables stored inside the control handler
|
||||
*/
|
||||
void getMousePositionInBuffer(){
|
||||
private void getMousePositionInBuffer(){
|
||||
//only if not headless, gather position
|
||||
if(!Globals.HEADLESS){
|
||||
glfwGetCursorPos(Globals.window, this.mouseState.getMouseBufferX(), this.mouseState.getMouseBufferY());
|
||||
@ -404,7 +404,7 @@ public class ControlHandler {
|
||||
* Checks if the mouse button 1 is currently pressed
|
||||
* @return true if pressed, false otherwise
|
||||
*/
|
||||
boolean getButton1Raw(){
|
||||
private boolean getButton1Raw(){
|
||||
if(Globals.HEADLESS){
|
||||
return false;
|
||||
} else {
|
||||
@ -416,7 +416,7 @@ public class ControlHandler {
|
||||
* Checks if the mouse button 2 is currently pressed
|
||||
* @return true if pressed, false otherwise
|
||||
*/
|
||||
boolean getButton2Raw(){
|
||||
private boolean getButton2Raw(){
|
||||
if(Globals.HEADLESS){
|
||||
return false;
|
||||
} else {
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
package electrosphere.controls;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
|
||||
/**
|
||||
* Utilities for dealing with cursors
|
||||
*/
|
||||
public class PlayerCursor {
|
||||
|
||||
/**
|
||||
* Token for displaying cursor
|
||||
*/
|
||||
public static final String CURSOR_TOKEN = "CURSOR";
|
||||
|
||||
/**
|
||||
* Token for displaying block cursor
|
||||
*/
|
||||
public static final String CURSOR_BLOCK_TOKEN = "CURSOR_BLOCK";
|
||||
|
||||
/**
|
||||
* Clamps a real position to the nearest block
|
||||
* @param input The input real position
|
||||
* @return The real position clamped to the nearest block
|
||||
*/
|
||||
public static Vector3d clampPositionToNearestBlock(Vector3d input){
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
if(input.x % BlockChunkData.BLOCK_SIZE_MULTIPLIER > BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0){
|
||||
x = input.x - input.x % 0.25 + BlockChunkData.BLOCK_SIZE_MULTIPLIER + BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0;
|
||||
} else {
|
||||
x = input.x - input.x % 0.25 + BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0;
|
||||
}
|
||||
if(input.y % BlockChunkData.BLOCK_SIZE_MULTIPLIER > BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0){
|
||||
y = input.y - input.y % 0.25 + BlockChunkData.BLOCK_SIZE_MULTIPLIER + BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0;
|
||||
} else {
|
||||
y = input.y - input.y % 0.25 + BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0;
|
||||
}
|
||||
if(input.z % BlockChunkData.BLOCK_SIZE_MULTIPLIER > BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0){
|
||||
z = input.z - input.z % 0.25 + BlockChunkData.BLOCK_SIZE_MULTIPLIER + BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0;
|
||||
} else {
|
||||
z = input.z - input.z % 0.25 + BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0;
|
||||
}
|
||||
return new Vector3d(x,y,z);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
package electrosphere.controls.categories;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_CONTROL;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@ -26,6 +28,7 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.Main;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityTags;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.entity.state.equip.ClientEquipState;
|
||||
import electrosphere.entity.state.equip.ClientToolbarState;
|
||||
@ -597,12 +600,23 @@ public class ControlCategoryMainGame {
|
||||
*/
|
||||
mainGameControlList.add(controlMap.get(TOOLBAR_SCROLL));
|
||||
controlMap.get(TOOLBAR_SCROLL).setOnScroll(new Control.ScrollCallback() {public void execute(MouseState mouseState, ScrollEvent scrollEvent){
|
||||
if(Globals.playerEntity != null && ClientToolbarState.getClientToolbarState(Globals.playerEntity) != null){
|
||||
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
|
||||
if(scrollEvent.getScrollAmount() > 0){
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() - 1);
|
||||
} else {
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() + 1);
|
||||
boolean handled = false;
|
||||
if(Globals.controlCallback.getKey(GLFW_KEY_LEFT_CONTROL)){
|
||||
//if the block cursor is visible, capture this input and instead modify block cursor
|
||||
if(Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE).contains(Globals.playerBlockCursor)){
|
||||
Globals.cursorState.updateCursorSize(scrollEvent);
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!handled){
|
||||
if(Globals.playerEntity != null && ClientToolbarState.getClientToolbarState(Globals.playerEntity) != null){
|
||||
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
|
||||
if(scrollEvent.getScrollAmount() > 0){
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() - 1);
|
||||
} else {
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
||||
223
src/main/java/electrosphere/controls/cursor/CursorState.java
Normal file
223
src/main/java/electrosphere/controls/cursor/CursorState.java
Normal file
@ -0,0 +1,223 @@
|
||||
package electrosphere.controls.cursor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.entity.DrawableUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityTags;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
import electrosphere.renderer.ui.events.ScrollEvent;
|
||||
|
||||
/**
|
||||
* Tracking for the cursor state
|
||||
*/
|
||||
public class CursorState {
|
||||
|
||||
/**
|
||||
* Token for displaying cursor
|
||||
*/
|
||||
public static final String CURSOR_TOKEN = "CURSOR";
|
||||
|
||||
/**
|
||||
* Token for displaying block cursor
|
||||
*/
|
||||
public static final String CURSOR_BLOCK_TOKEN = "CURSOR_BLOCK";
|
||||
|
||||
/**
|
||||
* Minimum size of the block cursor
|
||||
*/
|
||||
public static final int MIN_BLOCK_SIZE = 1;
|
||||
|
||||
/**
|
||||
* Maximum size of the block cursor
|
||||
*/
|
||||
public static final int MAX_BLOCK_SIZE = 4;
|
||||
|
||||
/**
|
||||
* The scale multiplier for scaling the block cursor
|
||||
*/
|
||||
private static final float BLOCK_CURSOR_SCALE_MULTIPLIER = 0.2f;
|
||||
|
||||
/**
|
||||
* Size of blocks to edit
|
||||
*/
|
||||
private int blockSize = MIN_BLOCK_SIZE;
|
||||
|
||||
/**
|
||||
* Creates the cursor entities
|
||||
*/
|
||||
public static void createCursorEntities(){
|
||||
//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);
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
|
||||
//player's block cursor
|
||||
Globals.playerBlockCursor = EntityCreationUtils.createClientSpatialEntity();
|
||||
EntityCreationUtils.makeEntityDrawable(Globals.playerBlockCursor, AssetDataStrings.UNITCUBE);
|
||||
Actor blockCursorActor = EntityUtils.getActor(Globals.playerBlockCursor);
|
||||
blockCursorActor.addTextureMask(new ActorTextureMask("cube", Arrays.asList(new String[]{"Textures/transparent_red.png"})));
|
||||
DrawableUtils.makeEntityTransparent(Globals.playerBlockCursor);
|
||||
EntityUtils.getScale(Globals.playerBlockCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the position of the player's in world cursor
|
||||
*/
|
||||
public void updatePlayerCursor(){
|
||||
CollisionEngine collisionEngine = Globals.clientSceneWrapper.getCollisionEngine();
|
||||
Entity camera = Globals.playerCamera;
|
||||
if(
|
||||
collisionEngine != null &&
|
||||
camera != null &&
|
||||
Globals.playerCursor != null
|
||||
){
|
||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(camera));
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||
Vector3d cursorPos = collisionEngine.rayCastPosition(centerPos, new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||
if(cursorPos == null){
|
||||
cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).normalize().mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE));
|
||||
}
|
||||
EntityUtils.getPosition(Globals.playerCursor).set(cursorPos);
|
||||
|
||||
//clamp block cursor to nearest voxel
|
||||
cursorPos.set(this.clampPositionToNearestBlock(cursorPos));
|
||||
EntityUtils.getPosition(Globals.playerBlockCursor).set(cursorPos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the real position cursor visible
|
||||
*/
|
||||
public static void makeRealVisible(){
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the block position cursor visible
|
||||
*/
|
||||
public static void makeBlockVisible(){
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the cursor
|
||||
*/
|
||||
public static void hide(){
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps a real position to the nearest block
|
||||
* @param input The input real position
|
||||
* @return The real position clamped to the nearest block
|
||||
*/
|
||||
public Vector3d clampPositionToNearestBlock(Vector3d input){
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
double sizeMult = BlockChunkData.BLOCK_SIZE_MULTIPLIER * blockSize;
|
||||
if(input.x % sizeMult > sizeMult / 2.0){
|
||||
x = input.x - input.x % sizeMult + sizeMult + sizeMult / 2.0;
|
||||
} else {
|
||||
x = input.x - input.x % sizeMult + sizeMult / 2.0;
|
||||
}
|
||||
if(input.y % sizeMult > sizeMult / 2.0){
|
||||
y = input.y - input.y % sizeMult + sizeMult + sizeMult / 2.0;
|
||||
} else {
|
||||
y = input.y - input.y % sizeMult + sizeMult / 2.0;
|
||||
}
|
||||
if(input.z % sizeMult > sizeMult / 2.0){
|
||||
z = input.z - input.z % sizeMult + sizeMult + sizeMult / 2.0;
|
||||
} else {
|
||||
z = input.z - input.z % sizeMult + sizeMult / 2.0;
|
||||
}
|
||||
return new Vector3d(x,y,z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps a real position to the corner of the block cursor
|
||||
* @param input The input real position
|
||||
* @return The corner position
|
||||
*/
|
||||
public Vector3d clampPositionToBlockCorner(Vector3d input){
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
double sizeMult = BlockChunkData.BLOCK_SIZE_MULTIPLIER * blockSize;
|
||||
if(input.x % sizeMult > sizeMult / 2.0){
|
||||
x = input.x - input.x % sizeMult + sizeMult;
|
||||
} else {
|
||||
x = input.x - input.x % sizeMult;
|
||||
}
|
||||
if(input.y % sizeMult > sizeMult / 2.0){
|
||||
y = input.y - input.y % sizeMult + sizeMult;
|
||||
} else {
|
||||
y = input.y - input.y % sizeMult;
|
||||
}
|
||||
if(input.z % sizeMult > sizeMult / 2.0){
|
||||
z = input.z - input.z % sizeMult + sizeMult;
|
||||
} else {
|
||||
z = input.z - input.z % sizeMult;
|
||||
}
|
||||
return new Vector3d(x,y,z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the voxel space position of the corner of the block cursor
|
||||
* @return The voxel space position
|
||||
*/
|
||||
public Vector3i getBlockCornerVoxelPos(){
|
||||
if(Globals.playerBlockCursor == null){
|
||||
throw new Error("Block cursor is null!");
|
||||
}
|
||||
Vector3d realPos = EntityUtils.getPosition(Globals.playerBlockCursor);
|
||||
Vector3d clamped = this.clampPositionToBlockCorner(realPos);
|
||||
return Globals.clientWorldData.convertRealToBlockSpace(clamped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cursor size
|
||||
* @param scrollEvent The scroll event
|
||||
*/
|
||||
public void updateCursorSize(ScrollEvent scrollEvent){
|
||||
if(scrollEvent.getScrollAmount() > 0){
|
||||
if(this.blockSize < MAX_BLOCK_SIZE){
|
||||
this.blockSize = this.blockSize * 2;
|
||||
}
|
||||
} else {
|
||||
if(this.blockSize > MIN_BLOCK_SIZE){
|
||||
this.blockSize = this.blockSize / 2;
|
||||
}
|
||||
}
|
||||
EntityUtils.getScale(Globals.playerBlockCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER * this.blockSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the size of the block cursor
|
||||
* @return The size of the block cursor
|
||||
*/
|
||||
public int getBlockSize(){
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
}
|
||||
@ -36,6 +36,7 @@ import electrosphere.controls.ControlCallback;
|
||||
import electrosphere.controls.ControlHandler;
|
||||
import electrosphere.controls.MouseCallback;
|
||||
import electrosphere.controls.ScrollCallback;
|
||||
import electrosphere.controls.cursor.CursorState;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.engine.assetmanager.AssetManager;
|
||||
import electrosphere.engine.loadingthreads.InitialAssetLoading;
|
||||
@ -203,6 +204,7 @@ public class Globals {
|
||||
public static ControlCallback controlCallback = new ControlCallback();
|
||||
public static MouseCallback mouseCallback = new MouseCallback();
|
||||
public static ScrollCallback scrollCallback = new ScrollCallback();
|
||||
public static CursorState cursorState = new CursorState();
|
||||
|
||||
|
||||
//
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package electrosphere.engine.loadingthreads;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
@ -18,22 +17,19 @@ import electrosphere.client.ui.menu.WindowStrings;
|
||||
import electrosphere.client.ui.menu.WindowUtils;
|
||||
import electrosphere.client.ui.menu.mainmenu.MenuCharacterCreation;
|
||||
import electrosphere.controls.ControlHandler;
|
||||
import electrosphere.controls.cursor.CursorState;
|
||||
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.EntityTags;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.NetUtils;
|
||||
import electrosphere.net.client.ClientNetworking;
|
||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||
import electrosphere.net.parser.net.message.LoreMessage;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
|
||||
public class ClientLoading {
|
||||
|
||||
@ -296,23 +292,7 @@ public class ClientLoading {
|
||||
// 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);
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
|
||||
//player's block cursor
|
||||
Globals.playerBlockCursor = EntityCreationUtils.createClientSpatialEntity();
|
||||
EntityCreationUtils.makeEntityDrawable(Globals.playerBlockCursor, AssetDataStrings.UNITCUBE);
|
||||
Actor blockCursorActor = EntityUtils.getActor(Globals.playerBlockCursor);
|
||||
blockCursorActor.addTextureMask(new ActorTextureMask("cube", Arrays.asList(new String[]{"Textures/transparent_red.png"})));
|
||||
DrawableUtils.makeEntityTransparent(Globals.playerBlockCursor);
|
||||
EntityUtils.getScale(Globals.playerBlockCursor).set(0.2f);
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
CursorState.createCursorEntities();
|
||||
|
||||
//cloud object
|
||||
// Entity cloudEnt = EntityCreationUtils.createClientSpatialEntity();
|
||||
|
||||
@ -18,7 +18,7 @@ import electrosphere.game.data.item.Item;
|
||||
import java.util.List;
|
||||
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
import electrosphere.controls.PlayerCursor;
|
||||
import electrosphere.controls.cursor.CursorState;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
@ -177,12 +177,11 @@ public class ClientToolbarState implements BehaviorTree {
|
||||
if(targetPoint != null && parent == Globals.playerEntity){
|
||||
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(toEquip);
|
||||
if(Globals.playerCursor != null && Globals.playerBlockCursor != null){
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
if(itemData.getTokens().contains(PlayerCursor.CURSOR_TOKEN)){
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||
} else if(itemData.getTokens().contains(PlayerCursor.CURSOR_BLOCK_TOKEN)) {
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||
CursorState.hide();
|
||||
if(itemData.getTokens().contains(CursorState.CURSOR_TOKEN)){
|
||||
CursorState.makeRealVisible();
|
||||
} else if(itemData.getTokens().contains(CursorState.CURSOR_BLOCK_TOKEN)) {
|
||||
CursorState.makeBlockVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import electrosphere.controls.PlayerCursor;
|
||||
import electrosphere.controls.cursor.CursorState;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.game.data.block.BlockType;
|
||||
@ -149,12 +149,13 @@ public class Item extends CommonEntityType {
|
||||
//set usage
|
||||
ItemUsage usage = new ItemUsage();
|
||||
usage.setBlockId(blockType.getId());
|
||||
usage.setOnlyOnMouseDown(true);
|
||||
rVal.setSecondaryUsage(usage);
|
||||
|
||||
|
||||
//attach common tokens
|
||||
List<String> tokens = new LinkedList<String>(Arrays.asList(DEFAULT_TOKENS));
|
||||
tokens.add(PlayerCursor.CURSOR_BLOCK_TOKEN);
|
||||
tokens.add(CursorState.CURSOR_BLOCK_TOKEN);
|
||||
rVal.setTokens(tokens);
|
||||
|
||||
return rVal;
|
||||
|
||||
@ -238,9 +238,9 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
||||
case UPDATEFLUIDDATA: {
|
||||
Globals.clientFluidManager.attachFluidMessage(message);
|
||||
} break;
|
||||
default:
|
||||
default: {
|
||||
LoggerInterface.loggerNetworking.WARNING("Client networking: Unhandled message of type: " + message.getMessageSubtype());
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
@ -245,6 +245,11 @@ public abstract class NetworkMessage {
|
||||
rVal = TerrainMessage.parseupdateFluidDataMessage(byteBuffer,pool);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITBLOCK:
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestEditBlockMessage(byteBuffer,pool);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_SERVER:
|
||||
|
||||
@ -28,6 +28,7 @@ public class TerrainMessage extends NetworkMessage {
|
||||
REQUESTFLUIDDATA,
|
||||
SENDFLUIDDATA,
|
||||
UPDATEFLUIDDATA,
|
||||
REQUESTEDITBLOCK,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,6 +61,7 @@ public class TerrainMessage extends NetworkMessage {
|
||||
int terrainValue;
|
||||
int blockType;
|
||||
int blockMetadata;
|
||||
int blockEditSize;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -445,6 +447,20 @@ public class TerrainMessage extends NetworkMessage {
|
||||
this.blockMetadata = blockMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets blockEditSize
|
||||
*/
|
||||
public int getblockEditSize() {
|
||||
return blockEditSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets blockEditSize
|
||||
*/
|
||||
public void setblockEditSize(int blockEditSize) {
|
||||
this.blockEditSize = blockEditSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the packet header from the buffer
|
||||
* @param byteBuffer The buffer
|
||||
@ -543,6 +559,12 @@ public class TerrainMessage extends NetworkMessage {
|
||||
return TerrainMessage.canParsesendFluidDataMessage(byteBuffer);
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA:
|
||||
return TerrainMessage.canParseupdateFluidDataMessage(byteBuffer);
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITBLOCK:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITBLOCK_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1203,6 +1225,43 @@ public class TerrainMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a message of type RequestEditBlock
|
||||
*/
|
||||
public static TerrainMessage parseRequestEditBlockMessage(CircularByteBuffer byteBuffer, MessagePool pool){
|
||||
TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE);
|
||||
rVal.messageType = TerrainMessageType.REQUESTEDITBLOCK;
|
||||
TerrainMessage.stripPacketHeader(byteBuffer);
|
||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setvoxelX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setvoxelY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setvoxelZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setblockType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setblockMetadata(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setblockEditSize(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a message of type RequestEditBlock
|
||||
*/
|
||||
public static TerrainMessage constructRequestEditBlockMessage(int worldX,int worldY,int worldZ,int voxelX,int voxelY,int voxelZ,int blockType,int blockMetadata,int blockEditSize){
|
||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTEDITBLOCK);
|
||||
rVal.setworldX(worldX);
|
||||
rVal.setworldY(worldY);
|
||||
rVal.setworldZ(worldZ);
|
||||
rVal.setvoxelX(voxelX);
|
||||
rVal.setvoxelY(voxelY);
|
||||
rVal.setvoxelZ(voxelZ);
|
||||
rVal.setblockType(blockType);
|
||||
rVal.setblockMetadata(blockMetadata);
|
||||
rVal.setblockEditSize(blockEditSize);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
void serialize(){
|
||||
byte[] intValues = new byte[8];
|
||||
@ -1667,6 +1726,49 @@ public class TerrainMessage extends NetworkMessage {
|
||||
rawBytes[18+i] = chunkData[i];
|
||||
}
|
||||
break;
|
||||
case REQUESTEDITBLOCK:
|
||||
rawBytes = new byte[2+4+4+4+4+4+4+4+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITBLOCK;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(worldX);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(worldY);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(worldZ);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(voxelX);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[14+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(voxelY);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[18+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(voxelZ);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[22+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(blockType);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[26+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(blockMetadata);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[30+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(blockEditSize);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[34+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
serialized = true;
|
||||
}
|
||||
|
||||
@ -84,6 +84,7 @@ public class TypeBytes {
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 14;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 15;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 16;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTEDITBLOCK = 17;
|
||||
/*
|
||||
Terrain packet sizes
|
||||
*/
|
||||
@ -99,6 +100,7 @@ public class TypeBytes {
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDBLOCKDATA_SIZE = 18;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATEBLOCK_SIZE = 34;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE = 14;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTEDITBLOCK_SIZE = 38;
|
||||
|
||||
/*
|
||||
Server subcategories
|
||||
|
||||
@ -7,10 +7,12 @@ import java.nio.ShortBuffer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
@ -18,6 +20,8 @@ import electrosphere.net.server.player.Player;
|
||||
import electrosphere.net.template.ServerProtocolTemplate;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.ServerWorldData;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
import electrosphere.server.physics.block.editing.ServerBlockEditing;
|
||||
import electrosphere.server.physics.fluid.manager.ServerFluidChunk;
|
||||
import electrosphere.server.physics.terrain.editing.TerrainEditing;
|
||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||
@ -80,6 +84,14 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
|
||||
message.getworldX(), message.getworldY(), message.getworldZ()
|
||||
);
|
||||
} break;
|
||||
case REQUESTEDITBLOCK: {
|
||||
LoggerInterface.loggerNetworking.DEBUG("(Server) Received request to edit block at " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ());
|
||||
Entity targetEntity = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||
Realm playerRealm = Globals.realmManager.getEntityRealm(targetEntity);
|
||||
Vector3i worldPos = new Vector3i(message.getworldX(),message.getworldY(),message.getworldZ());
|
||||
Vector3i blockPos = new Vector3i(message.getvoxelX(),message.getvoxelY(),message.getvoxelZ());
|
||||
ServerBlockEditing.editBlockArea(playerRealm, worldPos, blockPos, (short)message.getblockType(), (short)message.getblockMetadata(), message.getblockEditSize());
|
||||
} break;
|
||||
//all ignored message types
|
||||
case UPDATEFLUIDDATA:
|
||||
case RESPONSEMETADATA:
|
||||
|
||||
@ -52,6 +52,9 @@ import electrosphere.renderer.pipelines.debug.DebugContentPipeline;
|
||||
import electrosphere.renderer.shader.VisualShader;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
|
||||
/**
|
||||
* The main object for the rendering engine
|
||||
*/
|
||||
public class RenderingEngine {
|
||||
|
||||
|
||||
@ -139,10 +142,9 @@ public class RenderingEngine {
|
||||
*/
|
||||
public static VisualShader compositeAnimeOutline;
|
||||
|
||||
|
||||
// public static boolean renderHitboxes = false;
|
||||
// public static boolean renderPhysics = false;
|
||||
|
||||
/**
|
||||
* The light manager for the rendering engine
|
||||
*/
|
||||
LightManager lightManager;
|
||||
|
||||
public static int outputFramebuffer = 0;
|
||||
@ -178,7 +180,9 @@ public class RenderingEngine {
|
||||
RenderScreenPipeline renderScreenPipeline = new RenderScreenPipeline();
|
||||
ImGuiPipeline imGuiPipeline;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the opengl context
|
||||
*/
|
||||
public void createOpenglContext(){
|
||||
LoggerInterface.loggerRenderer.INFO("Create OpenGL Context");
|
||||
|
||||
@ -306,16 +310,11 @@ public class RenderingEngine {
|
||||
GL45.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
GL45.glClear(GL45.GL_COLOR_BUFFER_BIT | GL45.GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// //Hide the cursor and capture it
|
||||
// glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
|
||||
|
||||
//init screen rendering quadrant
|
||||
screenTextureVAO = createScreenTextureVAO();
|
||||
// initScreenTextureShaderProgram();
|
||||
screenTextureShaders = VisualShader.loadSpecificShader("/Shaders/core/screentexture/simple1/simple1.vs", "/Shaders/core/screentexture/simple1/simple1.fs");
|
||||
// screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs");
|
||||
|
||||
//default framebuffer
|
||||
defaultFramebuffer = new Framebuffer(GL_DEFAULT_FRAMEBUFFER);
|
||||
@ -354,7 +353,6 @@ public class RenderingEngine {
|
||||
}
|
||||
Texture lightBufferDepthTexture = lightDepthBuffer.getDepthTexture();
|
||||
RenderingEngine.lightBufferDepthTexture = lightBufferDepthTexture;
|
||||
// glEnable(GL_CULL_FACE); // enabled for shadow mapping
|
||||
|
||||
//
|
||||
//create volume depth framebuffer/shader for volumetric rendering
|
||||
@ -372,11 +370,6 @@ public class RenderingEngine {
|
||||
//
|
||||
//Game normals
|
||||
//
|
||||
/*
|
||||
gameImageNormalsTexture;
|
||||
static Framebuffer gameImageNormalsFramebuffer;
|
||||
static ShaderProgram renderNormalsShader;
|
||||
*/
|
||||
try {
|
||||
gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
@ -409,7 +402,6 @@ public class RenderingEngine {
|
||||
try {
|
||||
normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), normalsOutlineTexture);
|
||||
// normalsOutlineShader = ShaderProgram.loadSpecificShader("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
|
||||
Globals.assetManager.addShaderToQueue("Shaders/core/anime/outlineNormals.vs", "Shaders/core/anime/outlineNormals.fs");
|
||||
} catch(Exception e){
|
||||
LoggerInterface.loggerRenderer.ERROR(e);
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.server.physics.block.editing;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.controls.cursor.CursorState;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.interfaces.VoxelCellManager;
|
||||
|
||||
@ -44,4 +45,28 @@ public class ServerBlockEditing {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a series of block edits on an area of blocks. Basically has a sphere around the provided position that it attempts to add value to
|
||||
* @param realm The realm to modify in
|
||||
* @param worldPos The world position
|
||||
* @param voxelPos The block position within the chunk at the world position
|
||||
* @param type The new type of block
|
||||
* @param metadata The new metadata for the block
|
||||
* @param size The size of the area to edit
|
||||
*/
|
||||
public static void editBlockArea(Realm realm, Vector3i worldPos, Vector3i voxelPos, short type, short metadata, int size){
|
||||
if(size < CursorState.MIN_BLOCK_SIZE || size > CursorState.MAX_BLOCK_SIZE){
|
||||
throw new Error("Size out of bounds: " + size);
|
||||
}
|
||||
Vector3i pos = new Vector3i();
|
||||
for(int x = 0; x < size; x++){
|
||||
for(int y = 0; y < size; y++){
|
||||
for(int z = 0; z < size; z++){
|
||||
pos = new Vector3i(voxelPos).add(x,y,z);
|
||||
ServerBlockEditing.editBlockChunk(realm, worldPos, pos, type, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -124,6 +124,10 @@
|
||||
{
|
||||
"name" : "blockMetadata",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "blockEditSize",
|
||||
"type" : "FIXED_INT"
|
||||
}
|
||||
],
|
||||
"messageTypes" : [
|
||||
@ -311,6 +315,21 @@
|
||||
"worldZ",
|
||||
"chunkData"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "RequestEditBlock",
|
||||
"description" : "Requests that a block be edited on the server",
|
||||
"data" : [
|
||||
"worldX",
|
||||
"worldY",
|
||||
"worldZ",
|
||||
"voxelX",
|
||||
"voxelY",
|
||||
"voxelZ",
|
||||
"blockType",
|
||||
"blockMetadata",
|
||||
"blockEditSize"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user