hitbox fix + mountain gen
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-11-17 14:32:18 -05:00
parent d65efefc92
commit 596b0f6624
16 changed files with 477 additions and 48 deletions

View File

@ -70,7 +70,8 @@
"rotW": 1, "rotW": 1,
"offsetX" : 0.0, "offsetX" : 0.0,
"offsetY" : 0.5, "offsetY" : 0.5,
"offsetZ" : 0.0 "offsetZ" : 0.0,
"kinematic" : true
}, },
"interaction" : { "interaction" : {
"onInteract" : "menu", "onInteract" : "menu",

View File

@ -1056,6 +1056,11 @@ Update visuals on pine tree
Mountain generation work Mountain generation work
Implement crafting Implement crafting
Fix image panel test Fix image panel test
Add explicit kinematic flag in data
Fix hitbox destruction logic to not double-delete
(11/17/2024)
Mountain generation work

View File

@ -110,6 +110,9 @@ public class PhysicsEntityUtils {
if(physicsTemplate.isAngularlyStatic()){ if(physicsTemplate.isAngularlyStatic()){
Globals.clientSceneWrapper.getCollisionEngine().setAngularlyStatic(rigidBody, true); Globals.clientSceneWrapper.getCollisionEngine().setAngularlyStatic(rigidBody, true);
} }
if(physicsTemplate.getKinematic()){
Globals.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
}
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
@ -170,6 +173,9 @@ public class PhysicsEntityUtils {
if(physicsTemplate.isAngularlyStatic()){ if(physicsTemplate.isAngularlyStatic()){
Globals.clientSceneWrapper.getCollisionEngine().setAngularlyStatic(rigidBody, true); Globals.clientSceneWrapper.getCollisionEngine().setAngularlyStatic(rigidBody, true);
} }
if(physicsTemplate.getKinematic()){
Globals.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
}
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
@ -232,6 +238,9 @@ public class PhysicsEntityUtils {
if(physicsTemplate.isAngularlyStatic()){ if(physicsTemplate.isAngularlyStatic()){
Globals.clientSceneWrapper.getCollisionEngine().setAngularlyStatic(rigidBody, true); Globals.clientSceneWrapper.getCollisionEngine().setAngularlyStatic(rigidBody, true);
} }
if(physicsTemplate.getKinematic()){
Globals.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
}
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
@ -317,6 +326,9 @@ public class PhysicsEntityUtils {
if(physicsTemplate.isAngularlyStatic()){ if(physicsTemplate.isAngularlyStatic()){
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true); realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
} }
if(physicsTemplate.getKinematic()){
Globals.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
}
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
@ -377,6 +389,9 @@ public class PhysicsEntityUtils {
if(physicsTemplate.isAngularlyStatic()){ if(physicsTemplate.isAngularlyStatic()){
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true); realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
} }
if(physicsTemplate.getKinematic()){
Globals.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
}
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
@ -439,6 +454,9 @@ public class PhysicsEntityUtils {
if(physicsTemplate.isAngularlyStatic()){ if(physicsTemplate.isAngularlyStatic()){
realm.getCollisionEngine().setAngularlyStatic(rigidBody, true); realm.getCollisionEngine().setAngularlyStatic(rigidBody, true);
} }
if(physicsTemplate.getKinematic()){
Globals.clientSceneWrapper.getCollisionEngine().setKinematic(rigidBody);
}
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform); rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate); rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);

View File

@ -18,6 +18,12 @@ public class AssetDataStrings {
public static final String MODEL_PARTICLE = "particleModel"; public static final String MODEL_PARTICLE = "particleModel";
public static final String TEXTURE_PARTICLE = "particleTexture"; public static final String TEXTURE_PARTICLE = "particleTexture";
/**
* UI textures
*/
public static final String UI_FRAME_TEXTURE_DEFAULT_1 = "Textures/ui/uiFrame1.png";
public static final String UI_FRAME_TEXTURE_DEFAULT_2 = "Textures/ui/uiFrame2.png";
/** /**
* UI generic audio * UI generic audio
*/ */

View File

@ -529,6 +529,7 @@ public class HitboxCollectionState {
state = HitboxCollectionState.getHitboxState(entity); state = HitboxCollectionState.getHitboxState(entity);
state.manager.deregisterHitbox(state); state.manager.deregisterHitbox(state);
state.destroy(isServer); state.destroy(isServer);
entity.removeData(EntityDataStrings.HITBOX_DATA);
} }
return state; return state;
} }

View File

@ -517,8 +517,6 @@ public class ItemUtils {
//destroy physics //destroy physics
//this deregisters from all four & unhooks rigid bodies from the physics runtime //this deregisters from all four & unhooks rigid bodies from the physics runtime
Globals.clientSceneWrapper.getCollisionEngine().destroyPhysics(item); Globals.clientSceneWrapper.getCollisionEngine().destroyPhysics(item);
//destroy hitboxes
HitboxCollectionState.destroyHitboxState(item,false);
//destroy graphics //destroy graphics
ClientEntityUtils.destroyEntity(item); ClientEntityUtils.destroyEntity(item);
} }

View File

@ -10,17 +10,54 @@ public class CollidableTemplate {
*/ */
String type; String type;
/**
* The first dimension of the rigid body
*/
float dimension1; float dimension1;
/**
* The second dimension of the rigid body
*/
float dimension2; float dimension2;
/**
* The third dimension of the rigid body
*/
float dimension3; float dimension3;
/**
* The x component of the quaternion controlling the offset rotation of the body
*/
float rotX; float rotX;
/**
* The y component of the quaternion controlling the offset rotation of the body
*/
float rotY; float rotY;
/**
* The z component of the quaternion controlling the offset rotation of the body
*/
float rotZ; float rotZ;
/**
* The w component of the quaternion controlling the offset rotation of the body
*/
float rotW; float rotW;
/**
* The x component of the vector controlling the offset position of the body
*/
float offsetX; float offsetX;
/**
* The y component of the vector controlling the offset position of the body
*/
float offsetY; float offsetY;
/**
* The z component of the vector controlling the offset position of the body
*/
float offsetZ; float offsetZ;
/** /**
@ -43,6 +80,11 @@ public class CollidableTemplate {
*/ */
boolean angularlyStatic; boolean angularlyStatic;
/**
* Controls whether the body is kinematic (infinite mass) or not
*/
boolean kinematic;
/** /**
* The primitive shape type * The primitive shape type
* @return The primitive shape * @return The primitive shape
@ -51,42 +93,82 @@ public class CollidableTemplate {
return type; return type;
} }
/**
* Gets the first dimension of the rigid body
* @return The first dimension of the rigid body
*/
public float getDimension1() { public float getDimension1() {
return dimension1; return dimension1;
} }
/**
* Gets the second dimension of the rigid body
* @return The second dimension of the rigid body
*/
public float getDimension2() { public float getDimension2() {
return dimension2; return dimension2;
} }
/**
* Gets the third dimension of the rigid body
* @return The third dimension of the rigid body
*/
public float getDimension3() { public float getDimension3() {
return dimension3; return dimension3;
} }
/**
* Gets the x component of the quaternion controlling the offset rotation of the body
* @return The x component of the quaternion controlling the offset rotation of the body
*/
public float getRotX(){ public float getRotX(){
return rotX; return rotX;
} }
/**
* Gets the y component of the quaternion controlling the offset rotation of the body
* @return The y component of the quaternion controlling the offset rotation of the body
*/
public float getRotY(){ public float getRotY(){
return rotY; return rotY;
} }
/**
* Gets the z component of the quaternion controlling the offset rotation of the body
* @return The z component of the quaternion controlling the offset rotation of the body
*/
public float getRotZ(){ public float getRotZ(){
return rotZ; return rotZ;
} }
/**
* Gets the w component of the quaternion controlling the offset rotation of the body
* @return The w component of the quaternion controlling the offset rotation of the body
*/
public float getRotW(){ public float getRotW(){
return rotW; return rotW;
} }
/**
* Gets the x component of the vector controlling the offset position of the body
* @return The x component of the vector controlling the offset position of the body
*/
public float getOffsetX() { public float getOffsetX() {
return offsetX; return offsetX;
} }
/**
* Gets the y component of the vector controlling the offset position of the body
* @return The y component of the vector controlling the offset position of the body
*/
public float getOffsetY() { public float getOffsetY() {
return offsetY; return offsetY;
} }
/**
* Gets the z component of the vector controlling the offset position of the body
* @return The z component of the vector controlling the offset position of the body
*/
public float getOffsetZ() { public float getOffsetZ() {
return offsetZ; return offsetZ;
} }
@ -123,30 +205,70 @@ public class CollidableTemplate {
return this.angularlyStatic; return this.angularlyStatic;
} }
/**
* Sets the first dimension of the rigid body
* @return The first dimension of the rigid body
*/
public void setDimension1(float dimension1) { public void setDimension1(float dimension1) {
this.dimension1 = dimension1; this.dimension1 = dimension1;
} }
/**
* Sets the second dimension of the rigid body
* @return The second dimension of the rigid body
*/
public void setDimension2(float dimension2) { public void setDimension2(float dimension2) {
this.dimension2 = dimension2; this.dimension2 = dimension2;
} }
/**
* Sets the third dimension of the rigid body
* @return The third dimension of the rigid body
*/
public void setDimension3(float dimension3) { public void setDimension3(float dimension3) {
this.dimension3 = dimension3; this.dimension3 = dimension3;
} }
/**
* Sets the x component of the vector controlling the offset position of the body
* @return The x component of the vector controlling the offset position of the body
*/
public void setOffsetX(float offsetX) { public void setOffsetX(float offsetX) {
this.offsetX = offsetX; this.offsetX = offsetX;
} }
/**
* Sets the y component of the vector controlling the offset position of the body
* @return The y component of the vector controlling the offset position of the body
*/
public void setOffsetY(float offsetY) { public void setOffsetY(float offsetY) {
this.offsetY = offsetY; this.offsetY = offsetY;
} }
/**
* Sets the z component of the vector controlling the offset position of the body
* @return The z component of the vector controlling the offset position of the body
*/
public void setOffsetZ(float offsetZ) { public void setOffsetZ(float offsetZ) {
this.offsetZ = offsetZ; this.offsetZ = offsetZ;
} }
/**
* Gets whether the body is kinematic (infinite mass) or not
* @return true if the body is kinematic, false otherwise
*/
public boolean getKinematic() {
return kinematic;
}
/**
* Sets whether the body is kinematic (infinite mass) or not
* @param kinematic true if the body is kinematic, false otherwise
*/
public void setKinematic(boolean kinematic) {
this.kinematic = kinematic;
}

View File

@ -3,7 +3,6 @@ package electrosphere.net.synchronization.transport;
import electrosphere.entity.state.movement.editor.ServerEditorMovementTree; import electrosphere.entity.state.movement.editor.ServerEditorMovementTree;
import electrosphere.entity.state.movement.editor.ClientEditorMovementTree; import electrosphere.entity.state.movement.editor.ClientEditorMovementTree;
import electrosphere.util.Utilities;
import electrosphere.entity.state.equip.ServerToolbarState; import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.entity.state.equip.ClientToolbarState; import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.stance.ServerStanceComponent; import electrosphere.entity.state.stance.ServerStanceComponent;

View File

@ -1,19 +1,16 @@
package electrosphere.renderer.ui.elements; package electrosphere.renderer.ui.elements;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.lwjgl.opengl.GL40;
import org.lwjgl.util.yoga.YGLayout; import org.lwjgl.util.yoga.YGLayout;
import org.lwjgl.util.yoga.YGNode; import org.lwjgl.util.yoga.YGNode;
import org.lwjgl.util.yoga.Yoga; import org.lwjgl.util.yoga.Yoga;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.signal.Signal.SignalType; import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
@ -35,38 +32,70 @@ import electrosphere.renderer.ui.events.NavigationEvent;
*/ */
public class Window implements DrawableElement, ContainerElement, NavigableElement { public class Window implements DrawableElement, ContainerElement, NavigableElement {
static Vector3f color = new Vector3f(1.0f); /**
* The color of the window
*/
Vector3f color = new Vector3f(1.0f);
/**
* The child elements of this window
*/
List<Element> childList = new LinkedList<Element>(); List<Element> childList = new LinkedList<Element>();
/**
* The buffer to draw the contents of the window to
*/
Framebuffer widgetBuffer; Framebuffer widgetBuffer;
/**
* The material for the window
*/
Material customMat = new Material(); Material customMat = new Material();
/**
* The position of buffer texture within the render call for the window itself
*/
Vector3f texPosition = new Vector3f(0,0,0); Vector3f texPosition = new Vector3f(0,0,0);
/**
* The scale of buffer texture within the render call for the window itself
*/
Vector3f texScale = new Vector3f(1,1,0); Vector3f texScale = new Vector3f(1,1,0);
/**
* The navigation callback for the window
*/
NavigationEventCallback navCallback; NavigationEventCallback navCallback;
static final Vector3f windowDrawDebugColor = new Vector3f(1.0f,0.0f,0.0f);
/** /**
* Default width of popups * Default width of popups
*/ */
static final int DEFAULT_POPUP_WIDTH = 1000; static final int DEFAULT_POPUP_WIDTH = 1000;
/** /**
* Default height of popups * Default height of popups
*/ */
static final int DEFAULT_POPUP_HEIGHT = 1000; static final int DEFAULT_POPUP_HEIGHT = 1000;
//controls whether to show window decorations (ie the frame) /**
* Controls whether the decorations for the window draw or not
*/
boolean showDecorations = true; boolean showDecorations = true;
//Yoga node for controlling placement of the window on the screen /**
//IE, if you want to place a window in the upper right hand side of the screen, * Yoga node for controlling placement of the window on the screen
//this node can be used to control placement alignment to accomplish that * IE, if you want to place a window in the upper right hand side of the screen,
//NOTE: It should always be set to the current size of the window (width, height) * this node can be used to control placement alignment to accomplish that
//NOTE: It is updated every time the applyYoga function is called * NOTE: It should always be set to the current size of the window (width, height)
* NOTE: It is updated every time the applyYoga function is called
*/
long parentWindowYogaNode = -1; long parentWindowYogaNode = -1;
/**
* The frame decoration texture path
*/
String frameDecoration = AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_1;
/** /**
* Constructor * Constructor
* @param showDecorations * @param showDecorations
@ -186,12 +215,12 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
widgetBuffer.bind(openGLState); widgetBuffer.bind(openGLState);
openGLState.glViewport(width, height); openGLState.glViewport(width, height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL40.glClear(GL40.GL_COLOR_BUFFER_BIT | GL40.GL_DEPTH_BUFFER_BIT);
//grab assets required to render window //grab assets required to render window
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID); Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
Texture windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png"); Texture windowFrame = Globals.assetManager.fetchTexture(AssetDataStrings.UI_FRAME_TEXTURE_DEFAULT_1);
for(Element child : childList){ for(Element child : childList){
if(child instanceof DrawableElement){ if(child instanceof DrawableElement){
@ -227,7 +256,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions); planeModel.pushUniformToMesh("plane", "mDimension", boxDimensions);
planeModel.pushUniformToMesh("plane", "tPosition", texPosition); planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
planeModel.pushUniformToMesh("plane", "tDimension", texScale); planeModel.pushUniformToMesh("plane", "tDimension", texScale);
planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", color); planeModel.pushUniformToMesh(planeModel.getMeshes().get(0).getMeshName(), "color", new Vector3f(1.0f));
customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer()); customMat.setTexturePointer(widgetBuffer.getTexture().getTexturePointer());
planeModel.getMeshes().get(0).setMaterial(customMat); planeModel.getMeshes().get(0).setMaterial(customMat);
planeModel.drawUI(); planeModel.drawUI();
@ -239,7 +268,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
*/ */
public void destroy(){ public void destroy(){
this.yogaNode = Element.NULL_YOGA_ELEMENT; this.yogaNode = Element.NULL_YOGA_ELEMENT;
for(Element el : getChildren()){ for(Element el : this.getChildren()){
Globals.signalSystem.post(SignalType.YOGA_DESTROY, el); Globals.signalSystem.post(SignalType.YOGA_DESTROY, el);
} }
this.clearChildren(); this.clearChildren();
@ -252,7 +281,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
* clears all children * clears all children
*/ */
public void clear(){ public void clear(){
for(Element el : getChildren()){ for(Element el : this.getChildren()){
Globals.signalSystem.post(SignalType.YOGA_DESTROY, el); Globals.signalSystem.post(SignalType.YOGA_DESTROY, el);
} }
this.clearChildren(); this.clearChildren();
@ -836,4 +865,38 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeLeft, paddingLeft); Yoga.YGNodeStyleSetPadding(this.yogaNode, Yoga.YGEdgeLeft, paddingLeft);
} }
/**
* Gets the frame decoration texture path
* @return The frame decoration texture path
*/
public String getFrameDecoration() {
return frameDecoration;
}
/**
* Sets the frame decoration texture path
* @param frameDecoration The frame decoration texture path
*/
public void setFrameDecoration(String frameDecoration) {
this.frameDecoration = frameDecoration;
}
/**
* Gets the color of the window decorations
* @return The color of the decorations
*/
public Vector3f getColor() {
return color;
}
/**
* Sets the color of the window decorations
* @param color The color of the decorations
*/
public void setColor(Vector3f color) {
this.color = color;
}
} }

View File

@ -19,7 +19,6 @@ import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.entity.state.server.ServerPlayerViewDirTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.server.world.ServerWorldData; import electrosphere.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
@ -384,27 +383,36 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
} }
} }
for(ServerDataCell cell : toCleanQueue){ for(ServerDataCell cell : toCleanQueue){
boolean containsPlayerEntity = false;
//clear all entities in cell
for(Entity entity : cell.getScene().getEntityList()){
if(ServerPlayerViewDirTree.hasTree(entity)){
containsPlayerEntity = true;
break;
// int playerId = CreatureUtils.getControllerPlayerId(entity);
// Player player = Globals.playerManager.getPlayerFromId(playerId);
// throw new Error(
// "Trying to unload a player's entity! " +
// "entity: " + entity + "\n" +
// "entity pos (real): " + EntityUtils.getPosition(entity) + "\n" +
// "entity pos (world): " + serverWorldData.convertRealToWorldSpace(EntityUtils.getPosition(entity)) + "\n" +
// "chunk pos (world): " + worldPos + "\n" +
// "player pos (world): " + player.getWorldPos() + "\n" +
// "Number of players in cell: " + cell.getPlayers().size()
// );
}
// ServerEntityUtils.destroyEntity(entity);
}
if(containsPlayerEntity){
continue;
}
parent.deregisterCell(cell); parent.deregisterCell(cell);
Vector3i worldPos = getCellWorldPosition(cell); Vector3i worldPos = getCellWorldPosition(cell);
Long key = getServerDataCellKey(worldPos); Long key = getServerDataCellKey(worldPos);
groundDataCells.remove(key); groundDataCells.remove(key);
//offload all entities in cell to chunk file //offload all entities in cell to chunk file
serverContentManager.saveContentToDisk(key, cell.getScene().getEntityList()); serverContentManager.saveContentToDisk(key, cell.getScene().getEntityList());
//clear all entities in cell
for(Entity entity : cell.getScene().getEntityList()){ for(Entity entity : cell.getScene().getEntityList()){
if(ServerPlayerViewDirTree.hasTree(entity)){
int playerId = CreatureUtils.getControllerPlayerId(entity);
Player player = Globals.playerManager.getPlayerFromId(playerId);
throw new Error(
"Trying to unload a player's entity! " +
"entity: " + entity + "\n" +
"entity pos (real): " + EntityUtils.getPosition(entity) + "\n" +
"entity pos (world): " + serverWorldData.convertRealToWorldSpace(EntityUtils.getPosition(entity)) + "\n" +
"chunk pos (world): " + worldPos + "\n" +
"player pos (world): " + player.getWorldPos() + "\n" +
"Number of players in cell: " + cell.getPlayers().size()
);
}
ServerEntityUtils.destroyEntity(entity); ServerEntityUtils.destroyEntity(entity);
} }
//save terrain to disk //save terrain to disk

View File

@ -21,6 +21,7 @@ import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
import electrosphere.server.terrain.generation.interfaces.GenerationContext; import electrosphere.server.terrain.generation.interfaces.GenerationContext;
import electrosphere.server.terrain.generation.voxelphase.AnimeMountainsGen; import electrosphere.server.terrain.generation.voxelphase.AnimeMountainsGen;
import electrosphere.server.terrain.generation.voxelphase.HillsVoxelGen; import electrosphere.server.terrain.generation.voxelphase.HillsVoxelGen;
import electrosphere.server.terrain.generation.voxelphase.MountainVoxelGen;
import electrosphere.server.terrain.generation.voxelphase.VoxelGenerator; import electrosphere.server.terrain.generation.voxelphase.VoxelGenerator;
import electrosphere.server.terrain.manager.ServerTerrainChunk; import electrosphere.server.terrain.manager.ServerTerrainChunk;
import electrosphere.server.terrain.models.TerrainModel; import electrosphere.server.terrain.models.TerrainModel;
@ -91,6 +92,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
this.registerHeightmapGenerator(new MountainGen()); this.registerHeightmapGenerator(new MountainGen());
this.registerVoxelGenerator(new HillsVoxelGen()); this.registerVoxelGenerator(new HillsVoxelGen());
this.registerVoxelGenerator(new AnimeMountainsGen()); this.registerVoxelGenerator(new AnimeMountainsGen());
this.registerVoxelGenerator(new MountainVoxelGen());
this.useJavascript = useJavascript; this.useJavascript = useJavascript;
} }
@ -123,7 +125,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams(); BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag()); HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
heightmapGen = this.tagHeightmapMap.get("mountains"); heightmapGen = this.tagHeightmapMap.get("hills");
if(heightmapGen == null){ if(heightmapGen == null){
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag()); throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
} }
@ -147,6 +149,25 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
} }
} }
float[][] gradientField = new float[ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE][ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE];
for(int x = 0; x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; x++){
for(int z = 0; z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE; z++){
float deltaX = 0;
float deltaZ = 0;
if(x < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1){
deltaX = Math.abs(heightfield[x][z] - heightfield[x+1][z]);
} else {
deltaX = Math.abs(heightfield[x][z] - heightfield[x-1][z]);
}
if(z < ServerTerrainChunk.CHUNK_DATA_GENERATOR_SIZE - 1){
deltaX = Math.abs(heightfield[x][z] - heightfield[x][z+1]);
} else {
deltaX = Math.abs(heightfield[x][z] - heightfield[x][z-1]);
}
gradientField[x][z] = deltaX * deltaX + deltaZ * deltaZ;
}
}
VoxelGenerator voxelGenerator = this.tagVoxelMap.get("hills"); VoxelGenerator voxelGenerator = this.tagVoxelMap.get("hills");
if(this.useJavascript){ if(this.useJavascript){
@ -212,7 +233,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
finalWorldX, finalWorldY, finalWorldZ, finalWorldX, finalWorldY, finalWorldZ,
finalChunkX, finalChunkY, finalChunkZ, finalChunkX, finalChunkY, finalChunkZ,
stride, stride,
heightfield[x][z], heightfield[x][z], gradientField[x][z],
surfaceBiome, surfaceBiome,
generationContext generationContext
); );

View File

@ -1,5 +1,6 @@
package electrosphere.server.terrain.generation.heightmap; package electrosphere.server.terrain.generation.heightmap;
import electrosphere.util.noise.OpenSimplex2S;
import io.github.studiorailgun.NoiseUtils; import io.github.studiorailgun.NoiseUtils;
public class MountainGen implements HeightmapGenerator { public class MountainGen implements HeightmapGenerator {
@ -17,18 +18,20 @@ public class MountainGen implements HeightmapGenerator {
/** /**
* Vertical scale of the noise * Vertical scale of the noise
*/ */
static final float VERTICAL_SCALE = 1024.0f; static final float VERTICAL_SCALE = 512.0f;
/** /**
* Horizontal scale of the noise * Horizontal scale of the noise
*/ */
static final float HORIZONTAL_SCALE = 1024.0f; static final float HORIZONTAL_SCALE = 512.0f;
/** /**
* The power applied to the noise * The power applied to the noise
*/ */
static final float POWER_SCALE = 2; static final float POWER_SCALE = 2;
static final float RELAXATION_FACTOR = 0.13f;
/** /**
* The scale to apply to the coordinates * The scale to apply to the coordinates
*/ */
@ -52,15 +55,40 @@ public class MountainGen implements HeightmapGenerator {
* @return The height * @return The height
*/ */
public float getHeight(long SEED, double x, double y){ public float getHeight(long SEED, double x, double y){
return this.getHeight1(SEED, x, y);
}
/**
* Gets the height at a given position for this generation approach
* @param SEED The seed
* @param x The x position
* @param y The y position
* @return The height
*/
public float getHeight1(long SEED, double x, double y){
float rVal = 0.0f; float rVal = 0.0f;
double smoothVoronoiSample = NoiseUtils.smoothVoronoi(x * GEN_SCALE, y * GEN_SCALE, (double)SEED, FALLOFF_FACTOR); double smoothVoronoiSample = NoiseUtils.smoothVoronoi(x * GEN_SCALE, y * GEN_SCALE, (double)SEED, FALLOFF_FACTOR);
double inverted = 1.0 - smoothVoronoiSample; double inverted = 1.0 - smoothVoronoiSample;
double minClamped = Math.max(inverted,0.0f); double noisy = inverted +
0.02 * OpenSimplex2S.noise2(SEED, x * GEN_SCALE * 3, y * GEN_SCALE * 3) +
0.005 * OpenSimplex2S.noise2(SEED, x * GEN_SCALE * 5, y * GEN_SCALE * 5)
;
double minClamped = Math.max(noisy,0.0f);
double powered = Math.pow(minClamped,POWER_SCALE); double powered = Math.pow(minClamped,POWER_SCALE);
rVal = (float)powered * VERTICAL_SCALE; rVal = (float)powered * VERTICAL_SCALE;
return rVal; return rVal;
} }
public float getHeight2(long SEED, double x, double y){
double invertedMinDist = (
1.0 * (NoiseUtils.voronoiRelaxed(x * GEN_SCALE, y * GEN_SCALE, RELAXATION_FACTOR)) +
0.5 * (NoiseUtils.voronoiRelaxed(x * 1.2 * GEN_SCALE, y * 1.2 * GEN_SCALE, RELAXATION_FACTOR)) +
0.3 * (NoiseUtils.voronoiRelaxed(x * 2 * GEN_SCALE, y * 2 * GEN_SCALE, RELAXATION_FACTOR))
);
return (float)(Math.max(invertedMinDist - 0.6,0) / 1.6 * VERTICAL_SCALE);
}
@Override @Override
public String getTag() { public String getTag() {

View File

@ -67,7 +67,7 @@ public class AnimeMountainsGen implements VoxelGenerator {
GeneratedVoxel voxel, GeneratedVoxel voxel,
int worldX, int worldY, int worldZ, int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
int stride, float surfaceHeight, int stride, float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
) { ) {

View File

@ -27,7 +27,7 @@ public class HillsVoxelGen implements VoxelGenerator {
int worldX, int worldY, int worldZ, int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
int stride, int stride,
float surfaceHeight, float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
){ ){

View File

@ -0,0 +1,158 @@
package electrosphere.server.terrain.generation.voxelphase;
import electrosphere.engine.Globals;
import electrosphere.game.data.biome.BiomeData;
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
import electrosphere.server.terrain.generation.interfaces.GenerationContext;
public class MountainVoxelGen implements VoxelGenerator {
/**
* The width of the surface in number of voxels
*/
public static final int SURFACE_VOXEL_WIDTH = 2;
/**
* Cutoff after which snow is placed
*/
public static final int SNOW_CUTOFF = 150;
/**
* Gradient cutoff after which dirt is placed
*/
public static final float GRADIENT_DIRT_CUTOFF = 0.1f;
@Override
public String getTag(){
return "mountains";
}
@Override
public void getVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
int stride,
float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome,
GenerationContext generationContext
){
Globals.profiler.beginAggregateCpuSample("HillsVoxelGen.getVoxel");
double realX = generationContext.getServerWorldData().convertVoxelToRealSpace(chunkX,worldX);
double realY = generationContext.getServerWorldData().convertVoxelToRealSpace(chunkY,worldY);
double realZ = generationContext.getServerWorldData().convertVoxelToRealSpace(chunkZ,worldZ);
double strideMultiplier = Math.pow(2,stride);
double heightDiff = realY - surfaceHeight;
double surfacePercent = HillsVoxelGen.getSurfaceWeight(surfaceHeight,realY,strideMultiplier);
Globals.profiler.endCpuSample();
if(heightDiff < -strideMultiplier * SURFACE_VOXEL_WIDTH){
this.getSubsurfaceVoxel(
voxel,
worldX, worldY, worldZ,
chunkX, chunkY, chunkZ,
realX, realY, realZ,
surfacePercent,
surfaceHeight, surfaceGradient,
surfaceBiome
);
} else if(heightDiff > 0) {
this.getOverSurfaceVoxel(
voxel,
worldX, worldY, worldZ,
chunkX, chunkY, chunkZ,
realX, realY, realZ,-
surfacePercent,
surfaceHeight, surfaceGradient,
surfaceBiome
);
} else {
this.getSurfaceVoxel(
voxel,
worldX, worldY, worldZ,
chunkX, chunkY, chunkZ,
realX, realY, realZ,
surfacePercent,
surfaceHeight, surfaceGradient,
surfaceBiome
);
}
}
/**
* Gets the voxel on the surface
* @return The voxel
*/
private void getSurfaceVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ,
double surfacePercent,
float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome
){
voxel.weight = (float)surfacePercent * 2 - 1;
voxel.type = 2;
if(realY > SNOW_CUTOFF){
voxel.type = 5;
} else {
if(surfaceGradient > GRADIENT_DIRT_CUTOFF){
voxel.type = 1;
}
}
}
/**
* Gets the voxel below the surface
* @return The voxel
*/
private void getSubsurfaceVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ,
double surfacePercent,
float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome
){
if(realY < surfaceHeight - 5){
voxel.weight = 1;
voxel.type = 6;
} else {
voxel.weight = 1;
voxel.type = 1;
}
}
/**
* Gets the voxel above the service
* @return The voxel
*/
private void getOverSurfaceVoxel(
GeneratedVoxel voxel,
int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ,
double realX, double realY, double realZ,
double surfacePercent,
float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome
){
voxel.weight = -1;
voxel.type = 0;
}
/**
* Calculates the weight of a voxel on the surface based on the surface height, the position of the voxel, and the stride multiplier
* @param surfaceHeight The surface height
* @param realPosY The position of the voxel
* @param strideMultiplier The stride multiplier
* @return The weight of the voxel
*/
protected static double getSurfaceWeight(double surfaceHeight, double realPosY, double strideMultiplier){
return ((surfaceHeight - realPosY) / strideMultiplier);
}
}

View File

@ -29,6 +29,7 @@ public interface VoxelGenerator {
* @param chunkZ The chunk z pos * @param chunkZ The chunk z pos
* @param stride The stride of the data * @param stride The stride of the data
* @param surfaceHeight The height of the surface at x,z * @param surfaceHeight The height of the surface at x,z
* @param surfaceGradient The rate of change in the surface at this point
* @param surfaceBiome The surface biome of the chunk * @param surfaceBiome The surface biome of the chunk
* @param generationContext The generation context * @param generationContext The generation context
*/ */
@ -37,7 +38,7 @@ public interface VoxelGenerator {
int worldX, int worldY, int worldZ, int worldX, int worldY, int worldZ,
int chunkX, int chunkY, int chunkZ, int chunkX, int chunkY, int chunkZ,
int stride, int stride,
float surfaceHeight, float surfaceHeight, float surfaceGradient,
BiomeData surfaceBiome, BiomeData surfaceBiome,
GenerationContext generationContext GenerationContext generationContext
); );