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" : [
|
"tokens" : [
|
||||||
"GRAVITY",
|
"GRAVITY",
|
||||||
"TARGETABLE",
|
"TARGETABLE",
|
||||||
"CURSOR"
|
"CURSOR_FAB"
|
||||||
],
|
],
|
||||||
"equipData": {
|
"equipData": {
|
||||||
"equipClass" : "tool"
|
"equipClass" : "tool"
|
||||||
|
|||||||
@ -1544,6 +1544,8 @@ Exporting block prefabs to compressed files
|
|||||||
Minor block fab improvements
|
Minor block fab improvements
|
||||||
Fab selection tool
|
Fab selection tool
|
||||||
Fab selection tool actually loads fab files
|
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 org.joml.Vector3i;
|
||||||
|
|
||||||
|
import electrosphere.renderer.meshgen.BlockMeshgenData;
|
||||||
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.physics.terrain.manager.ServerTerrainChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores data about a chunk of blocks
|
* Stores data about a chunk of blocks
|
||||||
*/
|
*/
|
||||||
public class BlockChunkData {
|
public class BlockChunkData implements BlockMeshgenData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of blocks in each dimension of a chunk
|
* Number of blocks in each dimension of a chunk
|
||||||
@ -283,7 +284,7 @@ public class BlockChunkData {
|
|||||||
* @return true if empty, false otherwise
|
* @return true if empty, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isEmpty(int x, int y, int z){
|
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;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,4 +392,13 @@ public class BlockChunkData {
|
|||||||
this.setHomogenousValue((short)homogenousValue);
|
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);
|
BlockFab fab = BlockFab.create(dimensions, types, metadata);
|
||||||
File exportLoc = new File("./assets/Data/fab/struct.block");
|
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) -> {
|
fabSelectionPanelWindow.addChild(FabSelectionPanel.createFabSelectionPanel((File selectedFile) -> {
|
||||||
BlockFab fab = BlockFab.read(selectedFile);
|
BlockFab fab = BlockFab.read(selectedFile);
|
||||||
LoggerInterface.loggerEngine.WARNING("" + fab.getDimensions());
|
LoggerInterface.loggerEngine.WARNING("" + fab.getDimensions());
|
||||||
|
Globals.cursorState.setSelectedFab(fab);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Globals.signalSystem.post(SignalType.YOGA_APPLY,fabSelectionPanelWindow);
|
Globals.signalSystem.post(SignalType.YOGA_APPLY,fabSelectionPanelWindow);
|
||||||
|
|||||||
@ -11,13 +11,16 @@ import electrosphere.client.interact.select.AreaSelection;
|
|||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||||
|
import electrosphere.engine.assetmanager.queue.QueuedModel;
|
||||||
import electrosphere.entity.DrawableUtils;
|
import electrosphere.entity.DrawableUtils;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityCreationUtils;
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.game.data.block.BlockFab;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.actor.ActorTextureMask;
|
import electrosphere.renderer.actor.ActorTextureMask;
|
||||||
|
import electrosphere.renderer.meshgen.BlockMeshgen;
|
||||||
import electrosphere.renderer.ui.events.ScrollEvent;
|
import electrosphere.renderer.ui.events.ScrollEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +43,11 @@ public class CursorState {
|
|||||||
*/
|
*/
|
||||||
public static final String CURSOR_AREA_TOKEN = "CURSOR_AREA";
|
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
|
* Minimum size of the block cursor
|
||||||
*/
|
*/
|
||||||
@ -65,6 +73,11 @@ public class CursorState {
|
|||||||
*/
|
*/
|
||||||
private AreaSelection areaCursorSelection = null;
|
private AreaSelection areaCursorSelection = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fab cursor
|
||||||
|
*/
|
||||||
|
static Entity playerFabCursor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the cursor entities
|
* Creates the cursor entities
|
||||||
*/
|
*/
|
||||||
@ -95,6 +108,14 @@ public class CursorState {
|
|||||||
DrawableUtils.makeEntityTransparent(Globals.playerAreaCursor);
|
DrawableUtils.makeEntityTransparent(Globals.playerAreaCursor);
|
||||||
EntityUtils.getScale(Globals.playerAreaCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
|
EntityUtils.getScale(Globals.playerAreaCursor).set(BLOCK_CURSOR_SCALE_MULTIPLIER);
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
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
|
//clamp block cursor to nearest voxel
|
||||||
cursorPos.set(this.clampPositionToNearestBlock(cursorPos));
|
cursorPos.set(this.clampPositionToNearestBlock(cursorPos));
|
||||||
EntityUtils.getPosition(Globals.playerBlockCursor).set(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
|
* Makes the real position cursor visible
|
||||||
*/
|
*/
|
||||||
public static void makeRealVisible(){
|
public static void makeRealVisible(){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
CursorState.hide();
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
|
||||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +156,7 @@ public class CursorState {
|
|||||||
* Makes the block position cursor visible
|
* Makes the block position cursor visible
|
||||||
*/
|
*/
|
||||||
public static void makeBlockVisible(){
|
public static void makeBlockVisible(){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
CursorState.hide();
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
|
||||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,11 +164,18 @@ public class CursorState {
|
|||||||
* Makes the area position cursor visible
|
* Makes the area position cursor visible
|
||||||
*/
|
*/
|
||||||
public static void makeAreaVisible(){
|
public static void makeAreaVisible(){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerCursor, EntityTags.DRAWABLE);
|
CursorState.hide();
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.playerBlockCursor, EntityTags.DRAWABLE);
|
|
||||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(Globals.playerAreaCursor, EntityTags.DRAWABLE);
|
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
|
* Hides the cursor
|
||||||
*/
|
*/
|
||||||
@ -156,6 +183,7 @@ public class CursorState {
|
|||||||
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);
|
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);
|
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
|
* Gets the size of the block cursor
|
||||||
|
|||||||
@ -10,12 +10,13 @@ import org.joml.Vector3i;
|
|||||||
|
|
||||||
import electrosphere.client.block.BlockChunkData;
|
import electrosphere.client.block.BlockChunkData;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
import electrosphere.renderer.meshgen.BlockMeshgenData;
|
||||||
import electrosphere.util.FileUtils;
|
import electrosphere.util.FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of blocks
|
* A collection of blocks
|
||||||
*/
|
*/
|
||||||
public class BlockFab {
|
public class BlockFab implements BlockMeshgenData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File version format
|
* 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
|
* @param file The file
|
||||||
*/
|
*/
|
||||||
public void save(File file){
|
public void write(File file){
|
||||||
int blockCount = dimensions.x * dimensions.y * dimensions.z;
|
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 y = 0; y < dims.y; y++){
|
||||||
for(int z = 0; z < dims.z; z++){
|
for(int z = 0; z < dims.z; z++){
|
||||||
types[i] = shortView.get();
|
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();
|
metadata[i] = shortView.get();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -163,4 +172,15 @@ public class BlockFab {
|
|||||||
return metadata;
|
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.Vector2f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
import org.joml.Vector3i;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL40;
|
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 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){
|
protected static void fillQuadMeshes(List<QuadMesh> quadMeshes, BlockMeshgenData data){
|
||||||
for(int z = 0; z < BlockChunkData.CHUNK_DATA_WIDTH; z++){
|
Vector3i dimensions = data.getDimensions();
|
||||||
for(int x = 0; x < BlockChunkData.CHUNK_DATA_WIDTH; x++){
|
for(int z = 0; z < dimensions.z; z++){
|
||||||
|
for(int x = 0; x < dimensions.x; x++){
|
||||||
QuadMesh currentQuad = null;
|
QuadMesh currentQuad = null;
|
||||||
for(int y = 0; y < BlockChunkData.CHUNK_DATA_WIDTH; y++){
|
for(int y = 0; y < dimensions.y; y++){
|
||||||
if(chunkData.isEmpty(x, y, z)){
|
if(data.isEmpty(x, y, z)){
|
||||||
if(currentQuad == null){
|
if(currentQuad == null){
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@ -101,12 +103,15 @@ public class BlockMeshgen {
|
|||||||
currentQuad.z = z;
|
currentQuad.z = z;
|
||||||
currentQuad.w = 1;
|
currentQuad.w = 1;
|
||||||
currentQuad.h = 1;
|
currentQuad.h = 1;
|
||||||
currentQuad.type = chunkData.getType(x, y, z);
|
currentQuad.type = data.getType(x, y, z);
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(currentQuad != null){
|
||||||
|
quadMeshes.add(currentQuad);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,7 +332,7 @@ public class BlockMeshgen {
|
|||||||
* @param chunkData The block chunk data
|
* @param chunkData The block chunk data
|
||||||
* @return The mesh data
|
* @return The mesh data
|
||||||
*/
|
*/
|
||||||
public static BlockMeshData rasterize(BlockChunkData chunkData){
|
public static BlockMeshData rasterize(BlockMeshgenData chunkData){
|
||||||
BlockMeshData rVal = new BlockMeshData();
|
BlockMeshData rVal = new BlockMeshData();
|
||||||
|
|
||||||
//calculate quad meshes
|
//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