work on rotating buildings on placement
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
086c6da72e
commit
2f05fc06dd
@ -49,7 +49,7 @@ public class BeginStructureNode implements AITreeNode {
|
|||||||
Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position);
|
Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position);
|
||||||
|
|
||||||
//add to macro data
|
//add to macro data
|
||||||
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, placementPos);
|
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, placementPos, VirtualStructure.ROT_FACE_NORTH);
|
||||||
struct.setRepairable(true);
|
struct.setRepairable(true);
|
||||||
struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath())));
|
struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath())));
|
||||||
// macroData.getStructures().add(struct);
|
// macroData.getStructures().add(struct);
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
package electrosphere.server.macro.structure;
|
package electrosphere.server.macro.structure;
|
||||||
|
|
||||||
import org.joml.AABBd;
|
import org.joml.AABBd;
|
||||||
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
import electrosphere.controls.cursor.CursorState;
|
||||||
import electrosphere.data.block.fab.BlockFab;
|
import electrosphere.data.block.fab.BlockFab;
|
||||||
import electrosphere.data.struct.StructureData;
|
import electrosphere.data.struct.StructureData;
|
||||||
import electrosphere.server.macro.MacroData;
|
import electrosphere.server.macro.MacroData;
|
||||||
@ -14,56 +16,84 @@ import electrosphere.util.annotation.Exclude;
|
|||||||
*/
|
*/
|
||||||
public class VirtualStructure implements MacroAreaObject {
|
public class VirtualStructure implements MacroAreaObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the structure to face east
|
||||||
|
*/
|
||||||
|
public static final int ROT_FACE_EAST = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the structure ot face north
|
||||||
|
*/
|
||||||
|
public static final int ROT_FACE_NORTH = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the structure to face west
|
||||||
|
*/
|
||||||
|
public static final int ROT_FACE_WEST = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates the structure to face south
|
||||||
|
*/
|
||||||
|
public static final int ROT_FACE_SOUTH = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the structure
|
* The id of the structure
|
||||||
*/
|
*/
|
||||||
int id;
|
private int id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The position of the structure
|
* The position of the structure
|
||||||
*/
|
*/
|
||||||
Vector3d position;
|
private Vector3d position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rotation of the fab
|
||||||
|
*/
|
||||||
|
private int rotation = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bounding box for the structure
|
* The bounding box for the structure
|
||||||
*/
|
*/
|
||||||
AABBd aabb;
|
private AABBd aabb;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path to the block fab for the structure
|
* The path to the block fab for the structure
|
||||||
*/
|
*/
|
||||||
String fabPath;
|
private String fabPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual fab
|
* The actual fab
|
||||||
*/
|
*/
|
||||||
@Exclude
|
@Exclude
|
||||||
BlockFab fab;
|
private BlockFab fab;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the structure
|
* The type of the structure
|
||||||
*/
|
*/
|
||||||
String type;
|
private String type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks whether this structure needs repairs or not
|
* Tracks whether this structure needs repairs or not
|
||||||
*/
|
*/
|
||||||
boolean repairable = false;
|
private boolean repairable = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a structure
|
* Creates a structure
|
||||||
* @param macroData The macro data
|
* @param macroData The macro data
|
||||||
* @param data The data
|
* @param data The data
|
||||||
* @param position The position
|
* @param position The position
|
||||||
|
* @param rotation The rotation of the structure
|
||||||
* @return The structure
|
* @return The structure
|
||||||
*/
|
*/
|
||||||
public static VirtualStructure createStructure(MacroData macroData, StructureData data, Vector3d position){
|
public static VirtualStructure createStructure(MacroData macroData, StructureData data, Vector3d position, int rotation){
|
||||||
VirtualStructure rVal = new VirtualStructure();
|
VirtualStructure rVal = new VirtualStructure();
|
||||||
rVal.fabPath = data.getFabPath();
|
rVal.fabPath = data.getFabPath();
|
||||||
rVal.fab = data.getFab();
|
rVal.fab = data.getFab();
|
||||||
rVal.type = data.getId();
|
rVal.type = data.getId();
|
||||||
rVal.position = position;
|
rVal.position = position;
|
||||||
rVal.aabb = new AABBd(new Vector3d(position), new Vector3d(position).add(data.getDimensions()));
|
rVal.rotation = rotation;
|
||||||
|
rVal.aabb = new AABBd();
|
||||||
|
VirtualStructure.setAABB(rVal.aabb, rVal.position, data.getDimensions(), rotation);
|
||||||
macroData.addStructure(rVal);
|
macroData.addStructure(rVal);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
@ -146,6 +176,40 @@ public class VirtualStructure implements MacroAreaObject {
|
|||||||
public void setId(int id){
|
public void setId(int id){
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the rotation of the structure
|
||||||
|
* @param rotation The rotation
|
||||||
|
*/
|
||||||
|
public void setRotation(int rotation){
|
||||||
|
this.rotation = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the rotation of the structure
|
||||||
|
* @return The rotation of the structure
|
||||||
|
*/
|
||||||
|
public int getRotation(){
|
||||||
|
return this.rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the aabb of this structure given a rotation, dims, and start position
|
||||||
|
* @param aabb The aabb to populate
|
||||||
|
* @param startPos The start position
|
||||||
|
* @param dims The dimensions of the structure
|
||||||
|
* @param rotation The rotation
|
||||||
|
*/
|
||||||
|
public static void setAABB(AABBd aabb, Vector3d startPos, Vector3d dims, int rotation){
|
||||||
|
//construct aabb based on rotation
|
||||||
|
Quaterniond rotationQuat = CursorState.getBlockRotation(rotation);
|
||||||
|
Vector3d dimVec = new Vector3d(dims);
|
||||||
|
rotationQuat.transform(dimVec);
|
||||||
|
Vector3d startVec = startPos;
|
||||||
|
Vector3d endVec = new Vector3d(startPos).add(dimVec);
|
||||||
|
aabb.setMin(Math.min(startVec.x,endVec.x),Math.min(startVec.y,endVec.y),Math.min(startVec.z,endVec.z));
|
||||||
|
aabb.setMax(Math.max(startVec.x,endVec.x),Math.max(startVec.y,endVec.y),Math.max(startVec.z,endVec.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,11 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.joml.AABBd;
|
import org.joml.AABBd;
|
||||||
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
|
import electrosphere.controls.cursor.CursorState;
|
||||||
import electrosphere.data.struct.StructureData;
|
import electrosphere.data.struct.StructureData;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
@ -212,6 +214,8 @@ public class TownLayout {
|
|||||||
closedSet.add(openHash);
|
closedSet.add(openHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// System.out.println("Structure count: " + town.getStructures(macroData).size());
|
||||||
|
|
||||||
town.setResolution(Town.TOWN_RES_MAX);
|
town.setResolution(Town.TOWN_RES_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,10 +256,23 @@ public class TownLayout {
|
|||||||
|
|
||||||
//offset applied to the scan location to not place it on top of the road
|
//offset applied to the scan location to not place it on top of the road
|
||||||
Vector3d roadOffset = null;
|
Vector3d roadOffset = null;
|
||||||
|
int rotation1 = VirtualStructure.ROT_FACE_WEST;
|
||||||
|
int rotation2 = VirtualStructure.ROT_FACE_EAST;
|
||||||
|
Vector3d rotOffset = new Vector3d();
|
||||||
|
Quaterniond rotQuat1 = null;
|
||||||
|
Quaterniond rotQuat2 = null;
|
||||||
if(isNorthSouth){
|
if(isNorthSouth){
|
||||||
roadOffset = new Vector3d(roadRadiusOffsetRaw,0,0);
|
roadOffset = new Vector3d(roadRadiusOffsetRaw,0,0);
|
||||||
|
rotation1 = VirtualStructure.ROT_FACE_SOUTH;
|
||||||
|
rotation2 = VirtualStructure.ROT_FACE_NORTH;
|
||||||
|
rotQuat1 = CursorState.getBlockRotation(rotation1);
|
||||||
|
rotQuat2 = CursorState.getBlockRotation(rotation2);
|
||||||
} else {
|
} else {
|
||||||
roadOffset = new Vector3d(0,0,roadRadiusOffsetRaw);
|
roadOffset = new Vector3d(0,0,roadRadiusOffsetRaw);
|
||||||
|
rotation1 = VirtualStructure.ROT_FACE_WEST;
|
||||||
|
rotation2 = VirtualStructure.ROT_FACE_EAST;
|
||||||
|
rotQuat1 = CursorState.getBlockRotation(rotation1);
|
||||||
|
rotQuat2 = CursorState.getBlockRotation(rotation2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//the position to try at
|
//the position to try at
|
||||||
@ -267,17 +284,29 @@ public class TownLayout {
|
|||||||
|
|
||||||
//scan along the length of the road
|
//scan along the length of the road
|
||||||
for(int i = roadRadiusOffsetRaw; i < len; i++){
|
for(int i = roadRadiusOffsetRaw; i < len; i++){
|
||||||
|
//update rotation spatial offset based on current struct
|
||||||
|
rotOffset.set(structureData.getDimensions());
|
||||||
|
rotQuat1.transform(rotOffset);
|
||||||
|
rotOffset.x = Math.min(rotOffset.x,0);
|
||||||
|
rotOffset.y = Math.min(rotOffset.y,0);
|
||||||
|
rotOffset.z = Math.min(rotOffset.z,0);
|
||||||
|
rotOffset.mul(-1);
|
||||||
|
|
||||||
|
|
||||||
//solve terrain position to place
|
//solve terrain position to place
|
||||||
currPos.set(startPoint).lerp(endPoint,i/(double)len).add(roadOffset);
|
currPos.set(startPoint).lerp(endPoint,i/(double)len).add(roadOffset);
|
||||||
// currPos.set(dir).mul(i).add(startPoint).add(roadOffset);
|
// currPos.set(dir).mul(i).add(startPoint).add(roadOffset);
|
||||||
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
|
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
|
||||||
//apply structure placement offset
|
//apply structure placement offset
|
||||||
currPos.add(structureData.getPlacementOffset());
|
currPos.add(structureData.getPlacementOffset());
|
||||||
|
//add offset to re-align after rotation
|
||||||
|
currPos.add(rotOffset);
|
||||||
|
|
||||||
//update aabb
|
//update aabb
|
||||||
aabb.setMin(currPos);
|
VirtualStructure.setAABB(aabb, currPos, structureData.getDimensions(), rotation1);
|
||||||
aabb.setMax(new Vector3d(currPos).add(structureData.getDimensions()));
|
|
||||||
if(!macroData.intersectsStruct(aabb)){
|
if(!macroData.intersectsStruct(aabb)){
|
||||||
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, currPos);
|
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, currPos, rotation1);
|
||||||
town.addStructure(struct);
|
town.addStructure(struct);
|
||||||
//TODO: once have successfully placed this structure type, pick a new one to place
|
//TODO: once have successfully placed this structure type, pick a new one to place
|
||||||
}
|
}
|
||||||
@ -285,16 +314,27 @@ public class TownLayout {
|
|||||||
|
|
||||||
//scan along the length of the road
|
//scan along the length of the road
|
||||||
for(int i = 0; i < len; i++){
|
for(int i = 0; i < len; i++){
|
||||||
|
//update rotation spatial offset based on current struct
|
||||||
|
rotOffset.set(structureData.getDimensions());
|
||||||
|
rotQuat2.transform(rotOffset);
|
||||||
|
rotOffset.x = Math.max(rotOffset.x,0);
|
||||||
|
rotOffset.y = Math.max(rotOffset.y,0);
|
||||||
|
rotOffset.z = Math.max(rotOffset.z,0);
|
||||||
|
rotOffset.mul(-1);
|
||||||
|
|
||||||
//solve terrain position to place
|
//solve terrain position to place
|
||||||
currPos.set(dir).mul(i).add(startPoint).sub(roadOffset).sub(structureData.getDimensions().x,0,structureData.getDimensions().z);
|
currPos.set(dir).mul(i).add(startPoint).sub(roadOffset).sub(structureData.getDimensions());
|
||||||
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
|
currPos.y = realm.getServerWorldData().getServerTerrainManager().getElevation(currPos);
|
||||||
//apply structure placement offset
|
//apply structure placement offset
|
||||||
currPos.add(structureData.getPlacementOffset());
|
currPos.add(structureData.getPlacementOffset());
|
||||||
|
//add offset to re-align after rotation
|
||||||
|
// currPos.add(5,0,5);
|
||||||
|
|
||||||
//update aabb
|
//update aabb
|
||||||
aabb.setMin(currPos);
|
VirtualStructure.setAABB(aabb, currPos, structureData.getDimensions(), rotation2);
|
||||||
aabb.setMax(new Vector3d(currPos).add(structureData.getDimensions()));
|
|
||||||
if(!macroData.intersectsStruct(aabb)){
|
if(!macroData.intersectsStruct(aabb)){
|
||||||
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, currPos);
|
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, currPos, rotation2);
|
||||||
town.addStructure(struct);
|
town.addStructure(struct);
|
||||||
//TODO: once have successfully placed this structure type, pick a new one to place
|
//TODO: once have successfully placed this structure type, pick a new one to place
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,11 +7,13 @@ import java.util.function.Consumer;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.joml.AABBd;
|
import org.joml.AABBd;
|
||||||
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
import electrosphere.client.block.BlockChunkCache;
|
import electrosphere.client.block.BlockChunkCache;
|
||||||
import electrosphere.client.block.BlockChunkData;
|
import electrosphere.client.block.BlockChunkData;
|
||||||
|
import electrosphere.controls.cursor.CursorState;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.server.datacell.ServerWorldData;
|
import electrosphere.server.datacell.ServerWorldData;
|
||||||
@ -223,8 +225,9 @@ public class ServerBlockChunkGenerationThread implements Runnable {
|
|||||||
Vector3i chunkPos = new Vector3i(worldX, worldY, worldZ);
|
Vector3i chunkPos = new Vector3i(worldX, worldY, worldZ);
|
||||||
Vector3i blockPos = new Vector3i(0,0,0);
|
Vector3i blockPos = new Vector3i(0,0,0);
|
||||||
Vector3d chunkRealPos = ServerWorldData.convertChunkToRealSpace(chunkPos);
|
Vector3d chunkRealPos = ServerWorldData.convertChunkToRealSpace(chunkPos);
|
||||||
Vector3i localBlockPos = new Vector3i();
|
Vector3d localBlockPos = new Vector3d();
|
||||||
Vector3d currRealPos = new Vector3d(chunkRealPos);
|
Vector3d currRealPos = new Vector3d(chunkRealPos);
|
||||||
|
Vector3d dimVec = new Vector3d();
|
||||||
//contains at least one structure
|
//contains at least one structure
|
||||||
for(int x = 0; x < BlockChunkData.CHUNK_DATA_WIDTH; x++){
|
for(int x = 0; x < BlockChunkData.CHUNK_DATA_WIDTH; x++){
|
||||||
for(int y = 0; y < BlockChunkData.CHUNK_DATA_WIDTH; y++){
|
for(int y = 0; y < BlockChunkData.CHUNK_DATA_WIDTH; y++){
|
||||||
@ -241,13 +244,38 @@ public class ServerBlockChunkGenerationThread implements Runnable {
|
|||||||
if(struct.getAABB().testPoint(currRealPos.x, currRealPos.y, currRealPos.z)){
|
if(struct.getAABB().testPoint(currRealPos.x, currRealPos.y, currRealPos.z)){
|
||||||
AABBd aabb = struct.getAABB();
|
AABBd aabb = struct.getAABB();
|
||||||
localBlockPos.set(
|
localBlockPos.set(
|
||||||
(int)((currRealPos.x - aabb.minX) / BlockChunkData.BLOCK_SIZE_MULTIPLIER),
|
(int)Math.round((currRealPos.x - aabb.minX) / BlockChunkData.BLOCK_SIZE_MULTIPLIER),
|
||||||
(int)((currRealPos.y - aabb.minY) / BlockChunkData.BLOCK_SIZE_MULTIPLIER),
|
(int)Math.round((currRealPos.y - aabb.minY) / BlockChunkData.BLOCK_SIZE_MULTIPLIER),
|
||||||
(int)((currRealPos.z - aabb.minZ) / BlockChunkData.BLOCK_SIZE_MULTIPLIER)
|
(int)Math.round((currRealPos.z - aabb.minZ) / BlockChunkData.BLOCK_SIZE_MULTIPLIER)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Quaterniond rotationQuat = CursorState.getBlockRotation(struct.getRotation());
|
||||||
|
rotationQuat.transform(localBlockPos);
|
||||||
|
dimVec.set(struct.getFab().getDimensions());
|
||||||
|
rotationQuat.transform(dimVec);
|
||||||
|
dimVec.absolute();
|
||||||
|
if(localBlockPos.x < 0){
|
||||||
|
localBlockPos.x = (int)(dimVec.x + localBlockPos.x);
|
||||||
|
}
|
||||||
|
if(localBlockPos.y < 0){
|
||||||
|
localBlockPos.y = (int)(dimVec.y + localBlockPos.y);
|
||||||
|
}
|
||||||
|
if(localBlockPos.z < 0){
|
||||||
|
localBlockPos.z = (int)(dimVec.z + localBlockPos.z);
|
||||||
|
}
|
||||||
|
localBlockPos.x = Math.round(localBlockPos.x);
|
||||||
|
localBlockPos.y = Math.round(localBlockPos.y);
|
||||||
|
localBlockPos.z = Math.round(localBlockPos.z);
|
||||||
//structure file might have dimensions larger than fab, so need to make sure we're inbounds on fab file to draw data from fab file
|
//structure file might have dimensions larger than fab, so need to make sure we're inbounds on fab file to draw data from fab file
|
||||||
if(localBlockPos.x < struct.getFab().getDimensions().x && localBlockPos.y < struct.getFab().getDimensions().y && localBlockPos.z < struct.getFab().getDimensions().z){
|
if(
|
||||||
short blocktype = struct.getFab().getType(localBlockPos.x,localBlockPos.y,localBlockPos.z);
|
(int)localBlockPos.x >= 0 &&
|
||||||
|
(int)localBlockPos.y >= 0 &&
|
||||||
|
(int)localBlockPos.z >= 0 &&
|
||||||
|
(int)localBlockPos.x < struct.getFab().getDimensions().x &&
|
||||||
|
(int)localBlockPos.y < struct.getFab().getDimensions().y &&
|
||||||
|
(int)localBlockPos.z < struct.getFab().getDimensions().z
|
||||||
|
){
|
||||||
|
short blocktype = struct.getFab().getType((int)localBlockPos.x,(int)localBlockPos.y,(int)localBlockPos.z);
|
||||||
chunk.setType(x, y, z, blocktype);
|
chunk.setType(x, y, z, blocktype);
|
||||||
placedBlock = true;
|
placedBlock = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ public class CharaSimulation {
|
|||||||
Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position);
|
Vector3d placementPos = StructurePlacementUtils.getPlacementPosition(macroData, structureData, position);
|
||||||
|
|
||||||
//add to macro data
|
//add to macro data
|
||||||
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, placementPos);
|
VirtualStructure struct = VirtualStructure.createStructure(macroData, structureData, placementPos, VirtualStructure.ROT_FACE_NORTH);
|
||||||
struct.setRepairable(true);
|
struct.setRepairable(true);
|
||||||
struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath())));
|
struct.setFab(BlockFab.read(FileUtils.getAssetFile(struct.getFabPath())));
|
||||||
CharacterUtils.addShelter(chara, struct);
|
CharacterUtils.addShelter(chara, struct);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user