fab tool work
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
ca9282d2e6
commit
2d26a8e73a
@ -132,7 +132,7 @@
|
||||
"tokens" : [
|
||||
"GRAVITY",
|
||||
"TARGETABLE",
|
||||
"CURSOR"
|
||||
"CURSOR_FAB"
|
||||
],
|
||||
"equipData": {
|
||||
"equipClass" : "tool"
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user