block area selection control
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
f7c6208a2a
commit
20c53b151b
@ -1536,6 +1536,9 @@ Audio on placing blocks
|
|||||||
Audio on placing/removing voxels
|
Audio on placing/removing voxels
|
||||||
Debounce item usage activations
|
Debounce item usage activations
|
||||||
Variable block editing size
|
Variable block editing size
|
||||||
|
Increase block cursor size
|
||||||
|
Block area selection
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -69,6 +69,11 @@ public class BlockChunkData {
|
|||||||
*/
|
*/
|
||||||
public static final int LOD_LOWEST_RES = LOD_SIXTEENTH_RES;
|
public static final int LOD_LOWEST_RES = LOD_SIXTEENTH_RES;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty block
|
||||||
|
*/
|
||||||
|
public static final short BLOCK_TYPE_EMPTY = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of block at a given position
|
* The type of block at a given position
|
||||||
|
|||||||
@ -0,0 +1,75 @@
|
|||||||
|
package electrosphere.client.block;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
|
import electrosphere.controls.cursor.CursorState;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for selecting blocks on the client
|
||||||
|
*/
|
||||||
|
public class ClientBlockSelection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects all blocks on the client
|
||||||
|
*/
|
||||||
|
public static void selectAllBlocks(){
|
||||||
|
Vector3d minPos = new Vector3d();
|
||||||
|
Vector3d maxPos = new Vector3d();
|
||||||
|
|
||||||
|
Vector3i minVoxelPos = new Vector3i();
|
||||||
|
Vector3i maxVoxelPos = new Vector3i();
|
||||||
|
|
||||||
|
Vector3i chunkPos = new Vector3i();
|
||||||
|
|
||||||
|
boolean encountered = false;
|
||||||
|
|
||||||
|
for(int x = 0; x < Globals.clientWorldData.getWorldDiscreteSize(); x++){
|
||||||
|
for(int y = 0; y < Globals.clientWorldData.getWorldDiscreteSize(); y++){
|
||||||
|
for(int z = 0; z < Globals.clientWorldData.getWorldDiscreteSize(); z++){
|
||||||
|
chunkPos = new Vector3i(x,y,z);
|
||||||
|
|
||||||
|
BlockChunkData blockChunkData = Globals.clientBlockManager.getChunkDataAtWorldPoint(chunkPos, 0);
|
||||||
|
if(blockChunkData.getHomogenousValue() == BlockChunkData.BLOCK_TYPE_EMPTY){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean foundVoxel = false;
|
||||||
|
for(int i = 0; i < BlockChunkData.CHUNK_DATA_WIDTH; i++){
|
||||||
|
for(int j = 0; j < BlockChunkData.CHUNK_DATA_WIDTH; j++){
|
||||||
|
for(int k = 0; k < BlockChunkData.CHUNK_DATA_WIDTH; k++){
|
||||||
|
if(blockChunkData.getType(i, j, k) == BlockChunkData.BLOCK_TYPE_EMPTY){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!foundVoxel){
|
||||||
|
foundVoxel = true;
|
||||||
|
minVoxelPos.set(i,j,k);
|
||||||
|
maxVoxelPos.set(i+1,j+1,k+1);
|
||||||
|
} else {
|
||||||
|
minVoxelPos.min(new Vector3i(i,j,k));
|
||||||
|
maxVoxelPos.max(new Vector3i(i+1,j+1,k+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d localMin = Globals.clientWorldData.convertBlockToRealSpace(chunkPos, minVoxelPos);
|
||||||
|
Vector3d localMax = Globals.clientWorldData.convertBlockToRealSpace(chunkPos, maxVoxelPos);
|
||||||
|
|
||||||
|
if(!encountered){
|
||||||
|
encountered = true;
|
||||||
|
minPos.set(localMin);
|
||||||
|
maxPos.set(localMax);
|
||||||
|
} else {
|
||||||
|
minPos.min(localMin);
|
||||||
|
maxPos.max(localMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorState.selectRectangularArea(minPos, maxPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -215,4 +215,28 @@ public class ClientWorldData {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a block position to a real position
|
||||||
|
* @param chunkPos The position of the chunk
|
||||||
|
* @param blockPos The position of the block within the chunk
|
||||||
|
* @return The real position corresponding to the block's position
|
||||||
|
*/
|
||||||
|
public double convertBlockToRealSpace(int chunkPos, int blockPos){
|
||||||
|
return ServerTerrainChunk.CHUNK_PLACEMENT_OFFSET * chunkPos + BlockChunkData.BLOCK_SIZE_MULTIPLIER * blockPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a block position to a real position
|
||||||
|
* @param chunkPos The chunk's position
|
||||||
|
* @param blockPos The block's position
|
||||||
|
* @return The real position
|
||||||
|
*/
|
||||||
|
public Vector3d convertBlockToRealSpace(Vector3i chunkPos, Vector3i blockPos){
|
||||||
|
return new Vector3d(
|
||||||
|
convertBlockToRealSpace(chunkPos.x, blockPos.x),
|
||||||
|
convertBlockToRealSpace(chunkPos.y, blockPos.y),
|
||||||
|
convertBlockToRealSpace(chunkPos.z, blockPos.z)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
package electrosphere.client.ui.menu.editor;
|
||||||
|
|
||||||
|
import electrosphere.client.block.ClientBlockSelection;
|
||||||
|
import imgui.ImGui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for drawing the area tab of the editor window
|
||||||
|
*/
|
||||||
|
public class ImGuiAreaTab {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the area tab
|
||||||
|
*/
|
||||||
|
protected static void draw(){
|
||||||
|
if(ImGui.button("Select all voxels")){
|
||||||
|
ClientBlockSelection.selectAllBlocks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -64,6 +64,10 @@ public class ImGuiEditorWindows {
|
|||||||
ImGui.text("hierarchy controls here");
|
ImGui.text("hierarchy controls here");
|
||||||
ImGui.endTabItem();
|
ImGui.endTabItem();
|
||||||
}
|
}
|
||||||
|
if(ImGui.beginTabItem("Areas")){
|
||||||
|
ImGuiAreaTab.draw();
|
||||||
|
ImGui.endTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.endTabBar();
|
ImGui.endTabBar();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,11 @@ public class CursorState {
|
|||||||
*/
|
*/
|
||||||
public static final String CURSOR_BLOCK_TOKEN = "CURSOR_BLOCK";
|
public static final String CURSOR_BLOCK_TOKEN = "CURSOR_BLOCK";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token for displaying a block area selection cursor
|
||||||
|
*/
|
||||||
|
public static final String CURSOR_AREA_TOKEN = "CURSOR_AREA";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum size of the block cursor
|
* Minimum size of the block cursor
|
||||||
*/
|
*/
|
||||||
@ -47,7 +52,7 @@ public class CursorState {
|
|||||||
/**
|
/**
|
||||||
* The scale multiplier for scaling the block cursor
|
* The scale multiplier for scaling the block cursor
|
||||||
*/
|
*/
|
||||||
private static final float BLOCK_CURSOR_SCALE_MULTIPLIER = 0.2f;
|
private static final float BLOCK_CURSOR_SCALE_MULTIPLIER = 0.25f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of blocks to edit
|
* Size of blocks to edit
|
||||||
@ -75,6 +80,15 @@ public class CursorState {
|
|||||||
DrawableUtils.makeEntityTransparent(Globals.playerBlockCursor);
|
DrawableUtils.makeEntityTransparent(Globals.playerBlockCursor);
|
||||||
EntityUtils.getScale(Globals.playerBlockCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
|
EntityUtils.getScale(Globals.playerBlockCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||||
|
|
||||||
|
//player's area cursor
|
||||||
|
Globals.playerAreaCursor = EntityCreationUtils.createClientSpatialEntity();
|
||||||
|
EntityCreationUtils.makeEntityDrawable(Globals.playerAreaCursor, AssetDataStrings.UNITCUBE);
|
||||||
|
Actor areaCursorActor = EntityUtils.getActor(Globals.playerAreaCursor);
|
||||||
|
areaCursorActor.addTextureMask(new ActorTextureMask("cube", Arrays.asList(new String[]{"Textures/transparent_red.png"})));
|
||||||
|
DrawableUtils.makeEntityTransparent(Globals.playerAreaCursor);
|
||||||
|
EntityUtils.getScale(Globals.playerAreaCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
|
||||||
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +121,7 @@ public class CursorState {
|
|||||||
*/
|
*/
|
||||||
public static void makeRealVisible(){
|
public static void makeRealVisible(){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||||
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
||||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,15 +130,41 @@ public class CursorState {
|
|||||||
*/
|
*/
|
||||||
public static void makeBlockVisible(){
|
public static void makeBlockVisible(){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||||
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
||||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the area position cursor visible
|
||||||
|
*/
|
||||||
|
public static void makeAreaVisible(){
|
||||||
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||||
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||||
|
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides the cursor
|
* Hides the cursor
|
||||||
*/
|
*/
|
||||||
public static void hide(){
|
public static void hide(){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||||
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects a rectangular area
|
||||||
|
* @param startPos The start position of the area
|
||||||
|
* @param endPos The end position of the area
|
||||||
|
*/
|
||||||
|
public static void selectRectangularArea(Vector3d startPos, Vector3d endPos){
|
||||||
|
Vector3d center = new Vector3d(startPos).add(endPos).mul(0.5f);
|
||||||
|
Vector3d scale = new Vector3d(startPos).sub(endPos).absolute();
|
||||||
|
EntityCreationUtils.makeEntityDrawable(Globals.playerAreaCursor, AssetDataStrings.UNITCUBE);
|
||||||
|
Actor areaCursorActor = EntityUtils.getActor(Globals.playerAreaCursor);
|
||||||
|
areaCursorActor.addTextureMask(new ActorTextureMask("cube", Arrays.asList(new String[]{"Textures/transparent_red.png"})));
|
||||||
|
EntityUtils.getPosition(Globals.playerAreaCursor).set(center);
|
||||||
|
EntityUtils.getScale(Globals.playerAreaCursor).set(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -407,6 +407,7 @@ public class Globals {
|
|||||||
//the player in world cursor
|
//the player in world cursor
|
||||||
public static Entity playerCursor;
|
public static Entity playerCursor;
|
||||||
public static Entity playerBlockCursor;
|
public static Entity playerBlockCursor;
|
||||||
|
public static Entity playerAreaCursor;
|
||||||
|
|
||||||
//the creature the player camera will orbit and will receive controlHandler movementTree updates
|
//the creature the player camera will orbit and will receive controlHandler movementTree updates
|
||||||
public static Entity playerEntity;
|
public static Entity playerEntity;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user