fab tool work
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2025-04-26 12:24:23 -04:00
parent ca9282d2e6
commit 2d26a8e73a
9 changed files with 139 additions and 22 deletions

View File

@ -132,7 +132,7 @@
"tokens" : [
"GRAVITY",
"TARGETABLE",
"CURSOR"
"CURSOR_FAB"
],
"equipData": {
"equipClass" : "tool"

View File

@ -1544,6 +1544,8 @@ Exporting block prefabs to compressed files
Minor block fab improvements
Fab selection tool
Fab selection tool actually loads fab files
Fix fab file reading
Fab tool can show transparent, loaded version of fab file

View File

@ -2,12 +2,13 @@ package electrosphere.client.block;
import org.joml.Vector3i;
import electrosphere.renderer.meshgen.BlockMeshgenData;
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
/**
* Stores data about a chunk of blocks
*/
public class BlockChunkData {
public class BlockChunkData implements BlockMeshgenData {
/**
* Number of blocks in each dimension of a chunk
@ -283,7 +284,7 @@ public class BlockChunkData {
* @return true if empty, false otherwise
*/
public boolean isEmpty(int x, int y, int z){
boolean empty = this.getType(x,y,z) == 0;
boolean empty = this.getType(x,y,z) == BlockChunkData.BLOCK_TYPE_EMPTY;
return empty;
}
@ -391,4 +392,13 @@ public class BlockChunkData {
this.setHomogenousValue((short)homogenousValue);
}
@Override
public Vector3i getDimensions() {
return new Vector3i(
BlockChunkData.CHUNK_DATA_WIDTH,
BlockChunkData.CHUNK_DATA_WIDTH,
BlockChunkData.CHUNK_DATA_WIDTH
);
}
}

View File

@ -115,7 +115,7 @@ public class ClientBlockSelection {
BlockFab fab = BlockFab.create(dimensions, types, metadata);
File exportLoc = new File("./assets/Data/fab/struct.block");
fab.save(exportLoc);
fab.write(exportLoc);
}
}

View File

@ -58,6 +58,7 @@ public class FabMenus {
fabSelectionPanelWindow.addChild(FabSelectionPanel.createFabSelectionPanel((File selectedFile) -> {
BlockFab fab = BlockFab.read(selectedFile);
LoggerInterface.loggerEngine.WARNING("" + fab.getDimensions());
Globals.cursorState.setSelectedFab(fab);
}));
Globals.signalSystem.post(SignalType.YOGA_APPLY,fabSelectionPanelWindow);

View File

@ -11,13 +11,16 @@ import electrosphere.client.interact.select.AreaSelection;
import electrosphere.collision.CollisionEngine;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.assetmanager.queue.QueuedModel;
import electrosphere.entity.DrawableUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.game.data.block.BlockFab;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.meshgen.BlockMeshgen;
import electrosphere.renderer.ui.events.ScrollEvent;
/**
@ -40,6 +43,11 @@ public class CursorState {
*/
public static final String CURSOR_AREA_TOKEN = "CURSOR_AREA";
/**
* Cursor that displays a fab
*/
public static final String CURSOR_FAB_TOKEN = "CURSOR_FAB";
/**
* Minimum size of the block cursor
*/
@ -65,6 +73,11 @@ public class CursorState {
*/
private AreaSelection areaCursorSelection = null;
/**
* The fab cursor
*/
static Entity playerFabCursor;
/**
* Creates the cursor entities
*/
@ -95,6 +108,14 @@ public class CursorState {
DrawableUtils.makeEntityTransparent(Globals.playerAreaCursor);
EntityUtils.getScale(Globals.playerAreaCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
//player's fab cursor
playerFabCursor = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(playerFabCursor, AssetDataStrings.UNITCUBE);
Actor fabCursorActor = EntityUtils.getActor(playerFabCursor);
fabCursorActor.addTextureMask(new ActorTextureMask("cube", Arrays.asList(new String[]{"Textures/transparent_red.png"})));
DrawableUtils.makeEntityTransparent(playerFabCursor);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(playerFabCursor, EntityTags.DRAWABLE);
}
/**
@ -119,6 +140,7 @@ public class CursorState {
//clamp block cursor to nearest voxel
cursorPos.set(this.clampPositionToNearestBlock(cursorPos));
EntityUtils.getPosition(Globals.playerBlockCursor).set(cursorPos);
EntityUtils.getPosition(CursorState.playerFabCursor).set(cursorPos);
}
}
@ -126,8 +148,7 @@ public class CursorState {
* Makes the real position cursor visible
*/
public static void makeRealVisible(){
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
CursorState.hide();
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
}
@ -135,8 +156,7 @@ public class CursorState {
* Makes the block position cursor visible
*/
public static void makeBlockVisible(){
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
CursorState.hide();
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
}
@ -144,11 +164,18 @@ public class CursorState {
* 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);
CursorState.hide();
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
}
/**
* Makes the fab placement cursor visible
*/
public static void makeFabVisible(){
CursorState.hide();
Globals.clientSceneWrapper.getScene().registerEntityToTag(CursorState.playerFabCursor, EntityTags.DRAWABLE);
}
/**
* Hides the cursor
*/
@ -156,6 +183,7 @@ public class CursorState {
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
Globals.clientSceneWrapper.getScene().removeEntityFromTag(CursorState.playerFabCursor, EntityTags.DRAWABLE);
}
/**
@ -258,6 +286,23 @@ public class CursorState {
}
EntityUtils.getScale(Globals.playerBlockCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER * this.blockSize);
}
/**
* Sets the block fab cursor's current fab
* @param fab The fab
*/
public void setSelectedFab(BlockFab fab){
QueuedModel queuedModel = new QueuedModel(() -> {
return BlockMeshgen.generateBlockModel(BlockMeshgen.rasterize(fab));
});
Globals.assetManager.queuedAsset(queuedModel);
EntityCreationUtils.makeEntityDrawablePreexistingModel(playerFabCursor, queuedModel.getPromisedPath());
Actor fabCursorActor = EntityUtils.getActor(playerFabCursor);
fabCursorActor.addTextureMask(new ActorTextureMask("cube", Arrays.asList(new String[]{"Textures/transparent_red.png"})));
DrawableUtils.makeEntityTransparent(playerFabCursor);
CursorState.makeFabVisible();
}
/**
* Gets the size of the block cursor

View File

@ -10,12 +10,13 @@ import org.joml.Vector3i;
import electrosphere.client.block.BlockChunkData;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.meshgen.BlockMeshgenData;
import electrosphere.util.FileUtils;
/**
* A collection of blocks
*/
public class BlockFab {
public class BlockFab implements BlockMeshgenData {
/**
* File version format
@ -63,10 +64,10 @@ public class BlockFab {
}
/**
* Saves this fab to a file
* Writes this fab to a file
* @param file The file
*/
public void save(File file){
public void write(File file){
int blockCount = dimensions.x * dimensions.y * dimensions.z;
@ -122,6 +123,14 @@ public class BlockFab {
for(int y = 0; y < dims.y; y++){
for(int z = 0; z < dims.z; z++){
types[i] = shortView.get();
i++;
}
}
}
i = 0;
for(int x = 0; x < dims.x; x++){
for(int y = 0; y < dims.y; y++){
for(int z = 0; z < dims.z; z++){
metadata[i] = shortView.get();
i++;
}
@ -163,4 +172,15 @@ public class BlockFab {
return metadata;
}
@Override
public boolean isEmpty(int x, int y, int z){
boolean empty = this.getType(x,y,z) == BlockChunkData.BLOCK_TYPE_EMPTY;
return empty;
}
@Override
public short getType(int x, int y, int z) {
return this.types[x * dimensions.y * dimensions.z + y * dimensions.z + z];
}
}

View File

@ -9,6 +9,7 @@ import java.util.List;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL40;
@ -66,16 +67,17 @@ public class BlockMeshgen {
/**
* Calculates the quad meshes for the provided chunk data
* Calculates the quad meshes for the provided data
* @param quadMeshes The quad mesh list to fill
* @param chunkData The chunk data
* @param data The block data
*/
protected static void fillQuadMeshes(List<QuadMesh> quadMeshes, BlockChunkData chunkData){
for(int z = 0; z < BlockChunkData.CHUNK_DATA_WIDTH; z++){
for(int x = 0; x < BlockChunkData.CHUNK_DATA_WIDTH; x++){
protected static void fillQuadMeshes(List<QuadMesh> quadMeshes, BlockMeshgenData data){
Vector3i dimensions = data.getDimensions();
for(int z = 0; z < dimensions.z; z++){
for(int x = 0; x < dimensions.x; x++){
QuadMesh currentQuad = null;
for(int y = 0; y < BlockChunkData.CHUNK_DATA_WIDTH; y++){
if(chunkData.isEmpty(x, y, z)){
for(int y = 0; y < dimensions.y; y++){
if(data.isEmpty(x, y, z)){
if(currentQuad == null){
continue;
} else {
@ -101,12 +103,15 @@ public class BlockMeshgen {
currentQuad.z = z;
currentQuad.w = 1;
currentQuad.h = 1;
currentQuad.type = chunkData.getType(x, y, z);
currentQuad.type = data.getType(x, y, z);
} else {
continue;
}
}
}
if(currentQuad != null){
quadMeshes.add(currentQuad);
}
}
}
}
@ -327,7 +332,7 @@ public class BlockMeshgen {
* @param chunkData The block chunk data
* @return The mesh data
*/
public static BlockMeshData rasterize(BlockChunkData chunkData){
public static BlockMeshData rasterize(BlockMeshgenData chunkData){
BlockMeshData rVal = new BlockMeshData();
//calculate quad meshes

View File

@ -0,0 +1,34 @@
package electrosphere.renderer.meshgen;
import org.joml.Vector3i;
/**
* Interface for data that can be pased to the block meshgen function
*/
public interface BlockMeshgenData {
/**
* Checks if the data is empty at a position
* @param x The x position
* @param y The y position
* @param z The z position
* @return true if it is empty, false otherwise
*/
public boolean isEmpty(int x, int y, int z);
/**
* Gets the type at a given position
* @param x The x position
* @param y The y position
* @param z The z position
* @return The type
*/
public short getType(int x, int y, int z);
/**
* Gets the dimensions of this data
* @return The dimensions
*/
public Vector3i getDimensions();
}