fixes and cursor work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
8859b639ca
commit
c96c07334a
@ -1569,6 +1569,10 @@ Fix block meshgen
|
||||
(04/27/2025)
|
||||
Fab cursor rotation + actually place rotated fab
|
||||
Fix terrain and blocks not saving/loading to/from disk
|
||||
Fix swapping to/from editor entity in main game mode
|
||||
Block cursor work
|
||||
ChunkDiskMap code org
|
||||
Filter procedural worlds out of level select menu
|
||||
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.script.ScriptClientVoxelUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
|
||||
/**
|
||||
* Utilities for editing blocks
|
||||
@ -17,9 +16,9 @@ public class BlockEditing {
|
||||
* @param metadata The metadata of the block
|
||||
*/
|
||||
public static void editBlock(short type, short metadata){
|
||||
Vector3i cornerVoxel = Globals.cursorState.getBlockCornerVoxelPos();
|
||||
Vector3i cornerVoxel = Globals.clientWorldData.convertRealToBlockSpace(Globals.cursorState.getBlockCursorPos());
|
||||
int blockSize = Globals.cursorState.getBlockSize();
|
||||
Vector3i chunkPos = Globals.clientWorldData.convertRealToWorldSpace(EntityUtils.getPosition(Globals.playerBlockCursor));
|
||||
Vector3i chunkPos = Globals.clientWorldData.convertRealToWorldSpace(Globals.cursorState.getBlockCursorPos());
|
||||
ScriptClientVoxelUtils.clientRequestEditBlock(chunkPos, cornerVoxel, type, metadata, blockSize);
|
||||
}
|
||||
|
||||
@ -27,9 +26,9 @@ public class BlockEditing {
|
||||
* Destroy blocks
|
||||
*/
|
||||
public static void destroyBlock(){
|
||||
Vector3i cornerVoxel = Globals.cursorState.getBlockCornerVoxelPos();
|
||||
Vector3i cornerVoxel = Globals.clientWorldData.convertRealToBlockSpace(Globals.cursorState.getBlockCursorPos());
|
||||
int blockSize = Globals.cursorState.getBlockSize();
|
||||
Vector3i chunkPos = Globals.clientWorldData.convertRealToWorldSpace(EntityUtils.getPosition(Globals.playerBlockCursor));
|
||||
Vector3i chunkPos = Globals.clientWorldData.convertRealToWorldSpace(Globals.cursorState.getBlockCursorPos());
|
||||
ScriptClientVoxelUtils.clientRequestEditBlock(chunkPos, cornerVoxel, (short)0, (short)0, blockSize);
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,6 @@ import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkCache;
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.terrain.cache.ClientTerrainCache;
|
||||
import electrosphere.client.terrain.cells.ClientDrawCellManager;
|
||||
@ -39,13 +38,15 @@ import electrosphere.util.math.HashUtils;
|
||||
*/
|
||||
public class ClientTerrainManager {
|
||||
|
||||
//queues messages from server
|
||||
List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
|
||||
/**
|
||||
* queues messages from server
|
||||
*/
|
||||
private List<TerrainMessage> messageQueue = new LinkedList<TerrainMessage>();
|
||||
|
||||
/**
|
||||
* Locks the terrain manager (eg if adding message from network)
|
||||
*/
|
||||
static Semaphore lock = new Semaphore(1);
|
||||
private static Semaphore lock = new Semaphore(1);
|
||||
|
||||
/**
|
||||
* Maximum concurrent terrain requests
|
||||
@ -57,10 +58,14 @@ public class ClientTerrainManager {
|
||||
*/
|
||||
public static final int FAILED_REQUEST_THRESHOLD = 500;
|
||||
|
||||
//The interpolation ratio of terrain
|
||||
/**
|
||||
* The interpolation ratio of terrain
|
||||
*/
|
||||
public static final int INTERPOLATION_RATIO = ServerTerrainManager.SERVER_TERRAIN_MANAGER_INTERPOLATION_RATIO;
|
||||
|
||||
//caches chunks from server
|
||||
/**
|
||||
* caches chunks from server
|
||||
*/
|
||||
static final int CACHE_SIZE = 2500 + (int)(ClientDrawCellManager.FULL_RES_DIST * 10) + (int)(ClientDrawCellManager.HALF_RES_DIST * 10);
|
||||
|
||||
/**
|
||||
@ -71,37 +76,32 @@ public class ClientTerrainManager {
|
||||
/**
|
||||
* used for caching the macro values
|
||||
*/
|
||||
ClientTerrainCache terrainCache;
|
||||
private ClientTerrainCache terrainCache;
|
||||
|
||||
/**
|
||||
* Caches block data
|
||||
*/
|
||||
BlockChunkCache blockCache;
|
||||
|
||||
/**
|
||||
* The world data for the client
|
||||
*/
|
||||
ClientWorldData clientWorldData;
|
||||
private BlockChunkCache blockCache;
|
||||
|
||||
/**
|
||||
* The queue of terrain chunk data to be buffered to gpu
|
||||
*/
|
||||
static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new LinkedList<TerrainChunkGenQueueItem>();
|
||||
private static List<TerrainChunkGenQueueItem> terrainChunkGenerationQueue = new LinkedList<TerrainChunkGenQueueItem>();
|
||||
|
||||
/**
|
||||
* Tracks what outgoing requests are currently active
|
||||
*/
|
||||
Map<Long,Integer> requestedMap = new HashMap<Long,Integer>();
|
||||
private Map<Long,Integer> requestedMap = new HashMap<Long,Integer>();
|
||||
|
||||
/**
|
||||
* Tracks what outgoing block requests are currently active
|
||||
*/
|
||||
Map<Long,Integer> requestedBlockMap = new HashMap<Long,Integer>();
|
||||
private Map<Long,Integer> requestedBlockMap = new HashMap<Long,Integer>();
|
||||
|
||||
/**
|
||||
* Used to clear the request map
|
||||
*/
|
||||
List<Long> toClearFailedRequests = new LinkedList<Long>();
|
||||
private List<Long> toClearFailedRequests = new LinkedList<Long>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.client.ui.menu.mainmenu;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import electrosphere.client.ui.components.InputMacros;
|
||||
import electrosphere.client.ui.components.VoxelSelectionPanel;
|
||||
@ -114,7 +115,9 @@ public class MenuGeneratorsLevelEditor {
|
||||
existingLevelColumn.setAlignContent(YogaAlignment.Start);
|
||||
rVal.addChild(existingLevelColumn);
|
||||
|
||||
List<String> saveNames = SaveUtils.getSaves();
|
||||
List<String> saveNames = SaveUtils.getSaves().stream().filter((String saveName) -> {
|
||||
return !SaveUtils.isProcedural(saveName);
|
||||
}).collect(Collectors.toList());
|
||||
for(String saveName : saveNames){
|
||||
|
||||
//delete level button
|
||||
|
||||
@ -4,7 +4,6 @@ import java.util.Arrays;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
@ -249,20 +248,21 @@ public class CursorState {
|
||||
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;
|
||||
double alignMult = BlockChunkData.BLOCK_SIZE_MULTIPLIER;
|
||||
if(input.x % alignMult > alignMult / 2.0){
|
||||
x = input.x - input.x % alignMult + alignMult + sizeMult / 2.0;
|
||||
} else {
|
||||
x = input.x - input.x % sizeMult + sizeMult / 2.0;
|
||||
x = input.x - input.x % alignMult + sizeMult / 2.0;
|
||||
}
|
||||
if(input.y % sizeMult > sizeMult / 2.0){
|
||||
y = input.y - input.y % sizeMult + sizeMult + sizeMult / 2.0;
|
||||
if(input.y % alignMult > alignMult / 2.0){
|
||||
y = input.y - input.y % alignMult + alignMult + sizeMult / 2.0;
|
||||
} else {
|
||||
y = input.y - input.y % sizeMult + sizeMult / 2.0;
|
||||
y = input.y - input.y % alignMult + sizeMult / 2.0;
|
||||
}
|
||||
if(input.z % sizeMult > sizeMult / 2.0){
|
||||
z = input.z - input.z % sizeMult + sizeMult + sizeMult / 2.0;
|
||||
if(input.z % alignMult > alignMult / 2.0){
|
||||
z = input.z - input.z % alignMult + alignMult + sizeMult / 2.0;
|
||||
} else {
|
||||
z = input.z - input.z % sizeMult + sizeMult / 2.0;
|
||||
z = input.z - input.z % alignMult + sizeMult / 2.0;
|
||||
}
|
||||
return new Vector3d(x,y,z);
|
||||
}
|
||||
@ -276,36 +276,33 @@ public class CursorState {
|
||||
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;
|
||||
double alignMult = BlockChunkData.BLOCK_SIZE_MULTIPLIER;
|
||||
if(input.x % alignMult > alignMult / 2.0){
|
||||
x = input.x - input.x % alignMult + alignMult;
|
||||
} else {
|
||||
x = input.x - input.x % sizeMult;
|
||||
x = input.x - input.x % alignMult;
|
||||
}
|
||||
if(input.y % sizeMult > sizeMult / 2.0){
|
||||
y = input.y - input.y % sizeMult + sizeMult;
|
||||
if(input.y % alignMult > alignMult / 2.0){
|
||||
y = input.y - input.y % alignMult + alignMult;
|
||||
} else {
|
||||
y = input.y - input.y % sizeMult;
|
||||
y = input.y - input.y % alignMult;
|
||||
}
|
||||
if(input.z % sizeMult > sizeMult / 2.0){
|
||||
z = input.z - input.z % sizeMult + sizeMult;
|
||||
if(input.z % alignMult > alignMult / 2.0){
|
||||
z = input.z - input.z % alignMult + alignMult;
|
||||
} else {
|
||||
z = input.z - input.z % sizeMult;
|
||||
z = input.z - input.z % alignMult;
|
||||
}
|
||||
return new Vector3d(x,y,z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the voxel space position of the corner of the block cursor
|
||||
* @return The voxel space position
|
||||
* Gets the block cursor position
|
||||
* @return The block cursor 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);
|
||||
public Vector3d getBlockCursorPos(){
|
||||
double sizeMult = BlockChunkData.BLOCK_SIZE_MULTIPLIER * blockSize;
|
||||
Vector3d posRaw = new Vector3d(EntityUtils.getPosition(Globals.playerBlockCursor)).sub(sizeMult/2.0,sizeMult/2.0,sizeMult/2.0);
|
||||
return posRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -96,7 +96,7 @@ public class ClientToolbarState implements BehaviorTree {
|
||||
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
|
||||
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
|
||||
}
|
||||
equippedEntity = toEquip;
|
||||
equippedEntity = toEquip;
|
||||
|
||||
//
|
||||
//visual transforms
|
||||
|
||||
@ -117,7 +117,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
|
||||
*/
|
||||
static Entity swapPlayerCharacter(ServerConnectionHandler connectionHandler){
|
||||
//change the connection handler's creature template
|
||||
if(connectionHandler.getCurrentCreatureTemplate().getCreatureType().matches(LoadingUtils.EDITOR_RACE_NAME)){
|
||||
if(connectionHandler.getCurrentCreatureTemplate() != null && connectionHandler.getCurrentCreatureTemplate().getCreatureType().matches(LoadingUtils.EDITOR_RACE_NAME)){
|
||||
//solve what race to pick
|
||||
String race = LoadingUtils.EDITOR_RACE_NAME;
|
||||
List<String> races = Globals.gameConfigCurrent.getCreatureTypeLoader().getPlayableRaces();
|
||||
@ -173,7 +173,7 @@ public class CharacterProtocol implements ServerProtocolTemplate<CharacterMessag
|
||||
Player player = connectionHandler.getPlayer();
|
||||
Entity playerEntity = player.getPlayerEntity();
|
||||
Vector3d position = EntityUtils.getPosition(playerEntity);
|
||||
Globals.realmManager.getEntityRealm(playerEntity).registerSpawnPoint(position);;
|
||||
Globals.realmManager.getEntityRealm(playerEntity).registerSpawnPoint(position);
|
||||
Globals.realmManager.getEntityRealm(playerEntity).getSpawnPoint().set(position);
|
||||
ServerEntityUtils.destroyEntity(playerEntity);
|
||||
|
||||
|
||||
@ -26,6 +26,16 @@ import electrosphere.util.annotation.Exclude;
|
||||
*/
|
||||
public class ChunkDiskMap {
|
||||
|
||||
/**
|
||||
* Name of the map file
|
||||
*/
|
||||
static final String MAP_FILE_NAME = "voxelchunk.json";
|
||||
|
||||
/**
|
||||
* The directory that stores the voxel data files
|
||||
*/
|
||||
static final String VOXEL_DATA_DIR = "/terrain";
|
||||
|
||||
/**
|
||||
* The map of world position+chunk type to the file that actually houses that information
|
||||
*/
|
||||
@ -73,15 +83,15 @@ public class ChunkDiskMap {
|
||||
public static ChunkDiskMap init(String saveName){
|
||||
ChunkDiskMap rVal = null;
|
||||
LoggerInterface.loggerEngine.DEBUG("INIT CHUNK MAP " + saveName);
|
||||
if(FileUtils.getSaveFile(saveName, "chunk.map").exists()){
|
||||
rVal = FileUtils.loadObjectFromSavePath(saveName, "chunk.map", ChunkDiskMap.class);
|
||||
if(FileUtils.getSaveFile(saveName, MAP_FILE_NAME).exists()){
|
||||
rVal = FileUtils.loadObjectFromSavePath(saveName, MAP_FILE_NAME, ChunkDiskMap.class);
|
||||
LoggerInterface.loggerEngine.DEBUG("POS FILE MAP: " + rVal.worldPosFileMap.keySet());
|
||||
|
||||
//make sure the subfolder for chunk files exists
|
||||
String dirPath = SaveUtils.deriveSaveDirectoryPath(Globals.currentSave.getName());
|
||||
if(!Files.exists(new File(dirPath + "/terrain").toPath())){
|
||||
if(!Files.exists(new File(dirPath + VOXEL_DATA_DIR).toPath())){
|
||||
try {
|
||||
Files.createDirectories(new File(dirPath + "/terrain").toPath());
|
||||
Files.createDirectories(new File(dirPath + VOXEL_DATA_DIR).toPath());
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerFileIO.ERROR(e);
|
||||
}
|
||||
@ -104,7 +114,7 @@ public class ChunkDiskMap {
|
||||
* Saves the disk map to disk
|
||||
*/
|
||||
public void save(){
|
||||
FileUtils.serializeObjectToSavePath(Globals.currentSave.getName(), "chunk.map", this);
|
||||
FileUtils.serializeObjectToSavePath(Globals.currentSave.getName(), MAP_FILE_NAME, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,7 +223,7 @@ public class ChunkDiskMap {
|
||||
if(worldPosFileMap.containsKey(chunkKey)){
|
||||
fileName = worldPosFileMap.get(chunkKey);
|
||||
} else {
|
||||
fileName = "/terrain/" + chunkKey + ".dat";
|
||||
fileName = VOXEL_DATA_DIR + "/" + chunkKey + ".dat";
|
||||
}
|
||||
//generate binary for the file
|
||||
float[][][] weights = terrainChunk.getWeights();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user