Fix terrain editing
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
a34dc4a4dc
commit
5fee2d06af
@ -1132,6 +1132,8 @@ Disable tunnel noise to align foliage better + adjust manual value for foliage p
|
||||
(11/23/2024)
|
||||
Clean up top level folder
|
||||
Break out dependency documentation into a dedicated file
|
||||
Fix terrain editing
|
||||
Fix foliage not updating at edited chunk
|
||||
|
||||
|
||||
# TODO
|
||||
@ -1168,6 +1170,7 @@ Bug Fixes
|
||||
- Fix particles not spawning in correct positions
|
||||
- Fix flickering when applying yoga signal (may need to rethink arch here)
|
||||
- Fix virtual scrollables not working
|
||||
- Fix foliage flickering on edit
|
||||
|
||||
Startup Performance
|
||||
- Allow texture map to bind multiple model paths to a single set of mesh->textures
|
||||
|
||||
@ -154,6 +154,31 @@ public class ClientWorldData {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a relative voxel position to its absolute voxel equivalent
|
||||
* @param voxelPos The relative voxel position
|
||||
* @param worldPos The position of the chunk
|
||||
* @return The absolute voxel position ie the voxel-aligned position not clamped to the current chunk
|
||||
*/
|
||||
public Vector3i convertRelativeVoxelToAbsoluteVoxelSpace(Vector3i voxelPos, Vector3i worldPos){
|
||||
return new Vector3i(
|
||||
worldPos.x * ServerTerrainChunk.CHUNK_DIMENSION + voxelPos.x,
|
||||
worldPos.y * ServerTerrainChunk.CHUNK_DIMENSION + voxelPos.y,
|
||||
worldPos.z * ServerTerrainChunk.CHUNK_DIMENSION + voxelPos.z
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a relative voxel position to its absolute voxel equivalent
|
||||
* @param voxelPos The relative voxel position
|
||||
* @param worldPos The position of the chunk
|
||||
* @return The absolute voxel position ie the voxel-aligned position not clamped to the current chunk
|
||||
*/
|
||||
public int convertRelativeVoxelToAbsoluteVoxelSpace(int voxelPos, int worldPos){
|
||||
return worldPos * ServerTerrainChunk.CHUNK_DIMENSION + voxelPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a world space vector to a real space vector
|
||||
* @param position The world space vector
|
||||
|
||||
@ -14,6 +14,11 @@ import electrosphere.entity.Entity;
|
||||
*/
|
||||
public class ScriptClientVoxelUtils {
|
||||
|
||||
/**
|
||||
* Increment to edit terrain by
|
||||
*/
|
||||
static final float EDIT_INCREMENT = 0.1f;
|
||||
|
||||
/**
|
||||
* Applies the current voxel palette where the player's cursor is looking
|
||||
*/
|
||||
@ -29,7 +34,7 @@ public class ScriptClientVoxelUtils {
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||
Vector3d cursorPos = collisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
|
||||
if(Globals.clientSelectedVoxelType != null){
|
||||
TerrainEditing.editTerrain(cursorPos, 1.1f, Globals.clientSelectedVoxelType.getId(), 0.1f);
|
||||
TerrainEditing.editTerrain(cursorPos, 1.1f, Globals.clientSelectedVoxelType.getId(), EDIT_INCREMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ public class ChunkData {
|
||||
voxelWeight[localX][localY][localZ] = weight;
|
||||
voxelType[localX][localY][localZ] = type;
|
||||
//store as modified in cache
|
||||
String key = getVoxelPositionKey(new Vector3i(localX,localY,localZ));
|
||||
String key = this.getVoxelPositionKey(new Vector3i(localX,localY,localZ));
|
||||
if(!modifiedSinceLastGeneration.contains(key)){
|
||||
modifiedSinceLastGeneration.add(key);
|
||||
}
|
||||
|
||||
@ -799,8 +799,11 @@ public class ClientDrawCellManager {
|
||||
* @param worldY The world y position
|
||||
* @param worldZ The world z position
|
||||
*/
|
||||
public void markUpdateable(float worldX, float worldY, float worldZ){
|
||||
throw new Error("Unimplemented");
|
||||
public void markUpdateable(int worldX, int worldY, int worldZ){
|
||||
DrawCell drawCell = this.getDrawCell(worldX, worldY, worldZ);
|
||||
drawCell.ejectChunkData();
|
||||
drawCell.setHasGenerated(false);
|
||||
drawCell.setHasRequested(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -175,10 +175,11 @@ public class DrawCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
Entity toDelete = this.modelEntity;
|
||||
modelEntity = TerrainChunk.clientCreateTerrainChunkEntity(
|
||||
this.chunkData,
|
||||
this.notifyTarget,
|
||||
this.modelEntity,
|
||||
toDelete,
|
||||
lod,
|
||||
atlas,
|
||||
this.hasPolygons()
|
||||
@ -555,6 +556,13 @@ public class DrawCell {
|
||||
this.failedGenerationAttempts = this.failedGenerationAttempts + attempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejects the chunk data
|
||||
*/
|
||||
public void ejectChunkData(){
|
||||
this.chunkData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this draw cell is homogenous or not
|
||||
* @return true if it is homogenous, false otherwise
|
||||
|
||||
@ -19,7 +19,6 @@ import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.ClientEntityUtils;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityCreationUtils;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
@ -267,7 +266,6 @@ public class FoliageCell {
|
||||
this.chunkData = new TransvoxelChunkData(currentChunk.getVoxelWeight(), currentChunk.getVoxelType(), 0);
|
||||
}
|
||||
this.generate();
|
||||
this.setHasGenerated(true);
|
||||
}
|
||||
|
||||
|
||||
@ -276,9 +274,6 @@ public class FoliageCell {
|
||||
*/
|
||||
protected void generate(){
|
||||
boolean shouldGenerate = false;
|
||||
if(!Globals.clientDrawCellManager.hasGeneratedPhysics(worldPos.x, worldPos.y, worldPos.z)){
|
||||
return;
|
||||
}
|
||||
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPos,ChunkData.NO_STRIDE);
|
||||
if(data == null){
|
||||
return;
|
||||
@ -315,9 +310,12 @@ public class FoliageCell {
|
||||
if(shouldGenerate){
|
||||
Entity oldEntity = this.modelEntity;
|
||||
//create entity
|
||||
this.modelEntity = EntityCreationUtils.createClientSpatialEntity();
|
||||
FoliageModel.clientCreateFoliageChunkEntity(foliageTypesSupported,scale,this.modelEntity,this.getRealPos(),worldPos,voxelPos,notifyTarget,oldEntity);
|
||||
this.modelEntity = FoliageModel.clientCreateFoliageChunkEntity(foliageTypesSupported,scale,this.getRealPos(),worldPos,voxelPos,notifyTarget,oldEntity);
|
||||
} else {
|
||||
if(this.modelEntity != null){
|
||||
ClientEntityUtils.destroyEntity(this.modelEntity);
|
||||
this.modelEntity = null;
|
||||
}
|
||||
this.homogenous = true;
|
||||
}
|
||||
this.hasGenerated = true;
|
||||
@ -650,6 +648,13 @@ public class FoliageCell {
|
||||
this.failedGenerationAttempts = this.failedGenerationAttempts + attempts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejects the chunk data
|
||||
*/
|
||||
public void ejectChunkData(){
|
||||
this.chunkData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this foliage cell is homogenous or not
|
||||
* @return true if it is homogenous, false otherwise
|
||||
|
||||
@ -723,9 +723,18 @@ public class FoliageCellManager {
|
||||
* @param worldX The world x position
|
||||
* @param worldY The world y position
|
||||
* @param worldZ The world z position
|
||||
* @param voxelX The voxel x position
|
||||
* @param voxelY The voxel y position
|
||||
* @param voxelZ The voxel z position
|
||||
*/
|
||||
public void markUpdateable(float worldX, float worldY, float worldZ){
|
||||
throw new Error("Unimplemented");
|
||||
public void markUpdateable(int worldX, int worldY, int worldZ, int voxelX, int voxelY, int voxelZ){
|
||||
int absVoxelX = Globals.clientWorldData.convertRelativeVoxelToAbsoluteVoxelSpace(voxelX,worldX);
|
||||
int absVoxelY = Globals.clientWorldData.convertRelativeVoxelToAbsoluteVoxelSpace(voxelY,worldY);
|
||||
int absVoxelZ = Globals.clientWorldData.convertRelativeVoxelToAbsoluteVoxelSpace(voxelZ,worldZ);
|
||||
FoliageCell foliageCell = this.getFoliageCell(absVoxelX, absVoxelY, absVoxelZ);
|
||||
foliageCell.ejectChunkData();
|
||||
foliageCell.setHasGenerated(false);
|
||||
foliageCell.setHasRequested(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -137,7 +137,6 @@ public class FoliageModel {
|
||||
public static Entity clientCreateFoliageChunkEntity(
|
||||
List<String> foliageTypesSupported,
|
||||
int scale,
|
||||
Entity modelEntity,
|
||||
Vector3d realPos,
|
||||
Vector3i worldPos,
|
||||
Vector3i voxelPos,
|
||||
@ -218,11 +217,17 @@ public class FoliageModel {
|
||||
QueuedTexture queuedAsset = new QueuedTexture(buffer,textureWidth,textureHeight);
|
||||
Globals.assetManager.queuedAsset(queuedAsset);
|
||||
|
||||
TextureInstancedActor.attachTextureInstancedActor(modelEntity, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount, textureHeight);
|
||||
ClientEntityUtils.initiallyPositionEntity(modelEntity, realPos, new Quaterniond());
|
||||
EntityUtils.getScale(modelEntity).set(1,1,1);
|
||||
TextureInstancedActor.attachTextureInstancedActor(rVal, foliageType.getGraphicsTemplate().getModel().getPath(), vertexPath, fragmentPath, queuedAsset, drawCount, textureHeight);
|
||||
ClientEntityUtils.initiallyPositionEntity(rVal, realPos, new Quaterniond());
|
||||
EntityUtils.getScale(rVal).set(1,1,1);
|
||||
//add ambient foliage behavior tree
|
||||
AmbientFoliage.attachAmbientFoliageTree(modelEntity, 1.0f, foliageType.getGrowthModel().getGrowthRate());
|
||||
AmbientFoliage.attachAmbientFoliageTree(rVal, 1.0f, foliageType.getGrowthModel().getGrowthRate());
|
||||
}
|
||||
if(toDelete != null){
|
||||
ClientEntityUtils.destroyEntity(toDelete);
|
||||
}
|
||||
if(notifyTarget != null){
|
||||
notifyTarget.alertToGeneration();
|
||||
}
|
||||
} catch (Error e){
|
||||
LoggerInterface.loggerEngine.ERROR(e);
|
||||
|
||||
@ -10,6 +10,7 @@ import electrosphere.entity.state.attach.AttachUtils;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.renderer.actor.instance.TextureInstancedActor;
|
||||
|
||||
/**
|
||||
* Client only entity utility functions
|
||||
@ -55,6 +56,12 @@ public class ClientEntityUtils {
|
||||
//deregister all behavior trees
|
||||
EntityUtils.cleanUpEntity(entity);
|
||||
|
||||
//instanced actor
|
||||
if(TextureInstancedActor.getTextureInstancedActor(entity) != null){
|
||||
TextureInstancedActor actor = TextureInstancedActor.getTextureInstancedActor(entity);
|
||||
actor.free();
|
||||
}
|
||||
|
||||
if(Globals.clientSceneWrapper != null){
|
||||
Globals.clientSceneWrapper.getScene().deregisterEntity(entity);
|
||||
Globals.clientSceneWrapper.deregisterTranslationMapping(entity);
|
||||
|
||||
@ -107,13 +107,67 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
||||
//
|
||||
//mark all relevant drawcells as updateable
|
||||
for(Vector3i worldPosToUpdate : positionsToUpdate){
|
||||
if(Globals.clientTerrainManager.containsChunkDataAtWorldPoint(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z, ChunkData.NO_STRIDE)){
|
||||
ChunkData data = Globals.clientTerrainManager.getChunkDataAtWorldPoint(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z, ChunkData.NO_STRIDE);
|
||||
if(data != null){
|
||||
Globals.clientDrawCellManager.markUpdateable(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z);
|
||||
if(
|
||||
worldPosToUpdate.x >= 0 && worldPosToUpdate.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPosToUpdate.y >= 0 && worldPosToUpdate.y < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPosToUpdate.z >= 0 && worldPosToUpdate.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
//
|
||||
//mark terrain chunk for update
|
||||
Globals.clientDrawCellManager.markUpdateable(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z);
|
||||
|
||||
//
|
||||
//update foliage manager
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX(), message.getvoxelY(), message.getvoxelZ()
|
||||
);
|
||||
if(message.getvoxelX() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX() - 1, message.getvoxelY(), message.getvoxelZ()
|
||||
);
|
||||
if(message.getvoxelY() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX() - 1, message.getvoxelY() - 1, message.getvoxelZ()
|
||||
);
|
||||
if(message.getvoxelZ() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX() - 1, message.getvoxelY() - 1, message.getvoxelZ() - 1
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if(message.getvoxelZ() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX() - 1, message.getvoxelY(), message.getvoxelZ() - 1
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(message.getvoxelY() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX(), message.getvoxelY() - 1, message.getvoxelZ()
|
||||
);
|
||||
if(message.getvoxelZ() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX(), message.getvoxelY() - 1, message.getvoxelZ() - 1
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if(message.getvoxelZ() > 0){
|
||||
Globals.foliageCellManager.markUpdateable(
|
||||
worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z,
|
||||
message.getvoxelX(), message.getvoxelY(), message.getvoxelZ() - 1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Globals.clientFoliageManager.evaluateChunk(worldPos);
|
||||
}
|
||||
} break;
|
||||
case SENDFLUIDDATA: {
|
||||
|
||||
@ -28,13 +28,13 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
|
||||
public TerrainMessage handleAsyncMessage(ServerConnectionHandler connectionHandler, TerrainMessage message) {
|
||||
switch(message.getMessageSubtype()){
|
||||
case REQUESTCHUNKDATA: {
|
||||
sendWorldSubChunkAsync(connectionHandler,
|
||||
TerrainProtocol.sendWorldSubChunkAsync(connectionHandler,
|
||||
message.getworldX(), message.getworldY(), message.getworldZ()
|
||||
);
|
||||
return null;
|
||||
}
|
||||
case REQUESTREDUCEDCHUNKDATA: {
|
||||
sendWorldSubChunkAsyncStrided(connectionHandler,
|
||||
TerrainProtocol.sendWorldSubChunkAsyncStrided(connectionHandler,
|
||||
message.getworldX(), message.getworldY(), message.getworldZ(), message.getchunkResolution()
|
||||
);
|
||||
return null;
|
||||
@ -49,25 +49,25 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
|
||||
public void handleSyncMessage(ServerConnectionHandler connectionHandler, TerrainMessage message) {
|
||||
switch(message.getMessageSubtype()){
|
||||
case REQUESTMETADATA: {
|
||||
sendWorldMetadata(connectionHandler);
|
||||
TerrainProtocol.sendWorldMetadata(connectionHandler);
|
||||
} break;
|
||||
case REQUESTCHUNKDATA: {
|
||||
LoggerInterface.loggerNetworking.DEBUG("(Server) Received request for terrain " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ());
|
||||
// System.out.println("Received request for terrain " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ());
|
||||
sendWorldSubChunk(connectionHandler,
|
||||
TerrainProtocol.sendWorldSubChunk(connectionHandler,
|
||||
message.getworldX(), message.getworldY(), message.getworldZ()
|
||||
);
|
||||
} break;
|
||||
case REQUESTEDITVOXEL: {
|
||||
attemptTerrainEdit(connectionHandler, message);
|
||||
TerrainProtocol.attemptTerrainEdit(connectionHandler, message);
|
||||
} break;
|
||||
case REQUESTUSETERRAINPALETTE: {
|
||||
attemptUseTerrainEditPalette(connectionHandler, message);
|
||||
TerrainProtocol.attemptUseTerrainEditPalette(connectionHandler, message);
|
||||
} break;
|
||||
case REQUESTFLUIDDATA: {
|
||||
LoggerInterface.loggerNetworking.DEBUG("(Server) Received request for fluid " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ());
|
||||
// System.out.println("Received request for fluid " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ());
|
||||
sendWorldFluidSubChunk(connectionHandler,
|
||||
TerrainProtocol.sendWorldFluidSubChunk(connectionHandler,
|
||||
message.getworldX(), message.getworldY(), message.getworldZ()
|
||||
);
|
||||
} break;
|
||||
|
||||
@ -185,4 +185,13 @@ public class TextureInstancedActor {
|
||||
model.setWorldPos(worldPos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the texture instanced actor
|
||||
*/
|
||||
public void free(){
|
||||
if(this.queuedTexture != null && this.queuedTexture.getTexture() != null){
|
||||
Globals.assetManager.queueTextureForDeletion(this.queuedTexture.getTexture().getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -653,8 +653,6 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
*/
|
||||
public void editChunk(Vector3i worldPosition, Vector3i voxelPosition, float weight, int type) {
|
||||
terrainEditLock.acquireUninterruptibly();
|
||||
//update terrain
|
||||
serverTerrainManager.deformTerrainAtLocationToValue(worldPosition, voxelPosition, weight, type);
|
||||
List<Vector3i> worldPositionsToUpdate = new LinkedList<Vector3i>();
|
||||
worldPositionsToUpdate.add(worldPosition);
|
||||
if(voxelPosition.x < 1){
|
||||
@ -664,32 +662,45 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(1,1,1));
|
||||
}
|
||||
} else {
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(1,0,1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(voxelPosition.y < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(0,1,0));
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(0,1,1));
|
||||
}
|
||||
} else {
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(0,0,1));
|
||||
}
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(1,0,1));
|
||||
}
|
||||
}
|
||||
if(voxelPosition.y < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(0,1,0));
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(0,1,1));
|
||||
}
|
||||
}
|
||||
if(voxelPosition.z < 1){
|
||||
worldPositionsToUpdate.add(new Vector3i(worldPosition).sub(0,0,1));
|
||||
}
|
||||
//update all loaded cells
|
||||
for(Vector3i toUpdate : worldPositionsToUpdate){
|
||||
ServerDataCell cell = groundDataCells.get(getServerDataCellKey(toUpdate));
|
||||
if(cell != null){
|
||||
this.createTerrainPhysicsEntities(toUpdate);
|
||||
cell.broadcastNetworkMessage(TerrainMessage.constructUpdateVoxelMessage(
|
||||
worldPosition.x, worldPosition.y, worldPosition.z,
|
||||
voxelPosition.x, voxelPosition.y, voxelPosition.z,
|
||||
weight, type));
|
||||
if(
|
||||
toUpdate.x >= 0 && toUpdate.x < this.serverWorldData.getWorldSizeDiscrete() &&
|
||||
toUpdate.y >= 0 && toUpdate.y < this.serverWorldData.getWorldSizeDiscrete() &&
|
||||
toUpdate.z >= 0 && toUpdate.z < this.serverWorldData.getWorldSizeDiscrete()
|
||||
){
|
||||
//update terrain
|
||||
int localVoxelX = voxelPosition.x + (ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1) * (worldPosition.x - toUpdate.x);
|
||||
int localVoxelY = voxelPosition.y + (ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1) * (worldPosition.y - toUpdate.y);
|
||||
int localVoxelZ = voxelPosition.z + (ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1) * (worldPosition.z - toUpdate.z);
|
||||
serverTerrainManager.deformTerrainAtLocationToValue(toUpdate, new Vector3i(localVoxelX, localVoxelY, localVoxelZ), weight, type);
|
||||
|
||||
//update anything loaded
|
||||
ServerDataCell cell = groundDataCells.get(this.getServerDataCellKey(toUpdate));
|
||||
if(cell != null){
|
||||
//update physics
|
||||
this.createTerrainPhysicsEntities(toUpdate);
|
||||
|
||||
//broadcast update
|
||||
cell.broadcastNetworkMessage(TerrainMessage.constructUpdateVoxelMessage(
|
||||
toUpdate.x, toUpdate.y, toUpdate.z,
|
||||
localVoxelX, localVoxelY, localVoxelZ,
|
||||
weight, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
terrainEditLock.release();
|
||||
|
||||
@ -223,7 +223,7 @@ public class WorldOctTree <T> {
|
||||
){
|
||||
throw new Error("Trying to search for node outside tree range!");
|
||||
}
|
||||
WorldOctTreeNode<T> searchResult = recursiveSearchUnsafe(root,position,maxLevel);
|
||||
WorldOctTreeNode<T> searchResult = this.recursiveSearchUnsafe(root,position,maxLevel);
|
||||
if(!returnNonLeaf && !searchResult.isLeaf()){
|
||||
return null;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user