performance + ai work
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
5d1aebeaf2
commit
c9ac7496a5
@ -1665,6 +1665,12 @@ Debugging pathfinding code
|
||||
New AI behaviors
|
||||
- Will explore for resources if local ones aren't available
|
||||
Async pathfinding
|
||||
Fix interaction engine not properly destroying interaction data
|
||||
ClientSynchronizationManager does not store deleted entity IDs forever
|
||||
ClientSynchronizationManager un-deleted entity IDs when client receives creation message for an entity that was deleted
|
||||
MoveTo tree doesn't overwrite published status
|
||||
Fix AIManager.shutdown call not null checking
|
||||
Small explore node height offset
|
||||
|
||||
|
||||
|
||||
|
||||
@ -175,7 +175,21 @@ public class ClientInteractionEngine {
|
||||
public static void destroyCollidableTemplate(Entity rVal){
|
||||
lock.lock();
|
||||
CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine();
|
||||
interactionEngine.destroyPhysics(rVal);
|
||||
DBody body = null;
|
||||
Collidable collidable = null;
|
||||
if(rVal.containsKey(EntityDataStrings.INTERACTION_BODY)){
|
||||
body = (DBody)rVal.getData(EntityDataStrings.INTERACTION_BODY);
|
||||
}
|
||||
if(rVal.containsKey(EntityDataStrings.INTERACTION_COLLIDABLE)){
|
||||
collidable = (Collidable)rVal.getData(EntityDataStrings.INTERACTION_COLLIDABLE);
|
||||
}
|
||||
if(body != null){
|
||||
PhysicsUtils.destroyBody(interactionEngine, body);
|
||||
if(collidable != null){
|
||||
interactionEngine.deregisterCollisionObject(body, collidable);
|
||||
}
|
||||
}
|
||||
interactables.remove(rVal);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
@ -295,4 +309,27 @@ public class ClientInteractionEngine {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of interactibles on the client
|
||||
* @return The number of interactibles
|
||||
*/
|
||||
public static int getInteractiblesCount(){
|
||||
lock.lock();
|
||||
int rVal = interactables.size();
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of interactibles on the client
|
||||
* @return The number of interactibles
|
||||
*/
|
||||
public static int getCollidablesCount(){
|
||||
lock.lock();
|
||||
CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine();
|
||||
int rVal = interactionEngine.getCollidables().size();
|
||||
lock.unlock();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -24,17 +24,29 @@ import electrosphere.logger.LoggerInterface;
|
||||
*/
|
||||
public class ClientSceneWrapper {
|
||||
|
||||
//entity id translation between server/client
|
||||
/**
|
||||
* Translates client entity IDs to server IDs
|
||||
*/
|
||||
Map<Integer,Integer> clientToServerIdMap = new HashMap<Integer,Integer>();
|
||||
|
||||
/**
|
||||
* Translates server entity IDs to client IDs
|
||||
*/
|
||||
Map<Integer,Integer> serverToClientIdMap = new HashMap<Integer,Integer>();
|
||||
|
||||
//The list of server IDs that have been deleted
|
||||
/**
|
||||
* The list of server IDs that have been deleted
|
||||
*/
|
||||
Map<Integer,Boolean> deletedServerIds = new HashMap<Integer,Boolean>();
|
||||
|
||||
//The scene backing the wrapper
|
||||
/**
|
||||
* The scene backing the wrapper
|
||||
*/
|
||||
Scene scene;
|
||||
|
||||
//The engine used to back physics collision checks in client
|
||||
/**
|
||||
* The engine used to back physics collision checks in client
|
||||
*/
|
||||
CollisionEngine collisionEngine;
|
||||
|
||||
/**
|
||||
@ -47,7 +59,9 @@ public class ClientSceneWrapper {
|
||||
*/
|
||||
CollisionEngine interactionEngine;
|
||||
|
||||
//The hitbox manager
|
||||
/**
|
||||
* The hitbox manager
|
||||
*/
|
||||
HitboxManager hitboxManager;
|
||||
|
||||
/**
|
||||
@ -80,6 +94,7 @@ public class ClientSceneWrapper {
|
||||
lock.lock();
|
||||
clientToServerIdMap.put(clientId, serverId);
|
||||
serverToClientIdMap.put(serverId, clientId);
|
||||
Globals.clientSynchronizationManager.ejectDeletedKey(serverId);
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.client.ui.menu.debug;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||
import electrosphere.client.interact.ClientInteractionEngine;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.client.terrain.cells.DrawCell;
|
||||
import electrosphere.client.terrain.foliage.FoliageCell;
|
||||
@ -83,7 +84,8 @@ public class ImGuiClientServices {
|
||||
|
||||
|
||||
if(ImGui.collapsingHeader("Interaction Engine")){
|
||||
|
||||
ImGui.text("Interactible count: " + ClientInteractionEngine.getInteractiblesCount());
|
||||
ImGui.text("Collidables count: " + ClientInteractionEngine.getCollidablesCount());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -181,7 +181,7 @@ public class ImGuiWindowMacros {
|
||||
if(ImGui.button("Network Monitor")){
|
||||
ImGuiNetworkMonitor.netMonitorWindow.setOpen(true);
|
||||
}
|
||||
if(ImGui.button("Client Draw Cell Utils")){
|
||||
if(ImGui.button("Client Services")){
|
||||
ImGuiClientServices.clientServicesWindow.setOpen(true);
|
||||
}
|
||||
//close button
|
||||
|
||||
@ -613,6 +613,7 @@ public class CollisionEngine {
|
||||
public void deregisterCollisionObject(DBody body, Collidable collidable){
|
||||
spaceLock.lock();
|
||||
bodyPointerMap.remove(body);
|
||||
bodies.remove(body);
|
||||
collidableList.remove(collidable);
|
||||
spaceLock.unlock();
|
||||
}
|
||||
|
||||
@ -728,7 +728,9 @@ public class Globals {
|
||||
Globals.clientSynchronizationManager = new ClientSynchronizationManager();
|
||||
Globals.server = null;
|
||||
Globals.serverSynchronizationManager = new ServerSynchronizationManager();
|
||||
Globals.aiManager.shutdown();
|
||||
if(Globals.aiManager != null){
|
||||
Globals.aiManager.shutdown();
|
||||
}
|
||||
if(Globals.realmManager != null){
|
||||
Globals.realmManager.reset();
|
||||
}
|
||||
@ -740,7 +742,9 @@ public class Globals {
|
||||
*/
|
||||
public static void resetGlobals(){
|
||||
Globals.unloadScene();
|
||||
Globals.aiManager.shutdown();
|
||||
if(Globals.aiManager != null){
|
||||
Globals.aiManager.shutdown();
|
||||
}
|
||||
//
|
||||
//Actual globals to destroy
|
||||
Globals.assetManager = null;
|
||||
|
||||
@ -23,6 +23,7 @@ import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
@ -42,6 +43,11 @@ public class ClientSynchronizationManager {
|
||||
*/
|
||||
static final int MESSAGE_BOUNCE_WARNING_COUNT = 100;
|
||||
|
||||
/**
|
||||
* Number of frames to keep an entity deletion key around
|
||||
*/
|
||||
static final int DELETED_KEY_STORAGE_FRAMES = 10;
|
||||
|
||||
/**
|
||||
* The list of messages to loop through
|
||||
*/
|
||||
@ -55,7 +61,7 @@ public class ClientSynchronizationManager {
|
||||
/**
|
||||
* The list of Ids that the server has said to destroy
|
||||
*/
|
||||
List<Integer> deletedEntityIds = new LinkedList<Integer>();
|
||||
Map<Integer,Integer> deletedEntityIds = new HashMap<Integer,Integer>();
|
||||
|
||||
/**
|
||||
* Pushes a message into the queue to be processed
|
||||
@ -80,7 +86,7 @@ public class ClientSynchronizationManager {
|
||||
}
|
||||
|
||||
//remove sync messages if the entity was already deleted by the server
|
||||
if(this.deletedEntityIds.contains(message.getentityId())){
|
||||
if(this.deletedEntityIds.containsKey(message.getentityId())){
|
||||
messageBounceCount.remove(message);
|
||||
}
|
||||
|
||||
@ -182,6 +188,13 @@ public class ClientSynchronizationManager {
|
||||
messages.remove(message);
|
||||
Globals.clientConnection.release(message);
|
||||
}
|
||||
Set<Integer> deletionKeys = this.deletedEntityIds.keySet();
|
||||
for(int key : deletionKeys){
|
||||
int framesStored = this.deletedEntityIds.get(key);
|
||||
if(framesStored > DELETED_KEY_STORAGE_FRAMES){
|
||||
this.deletedEntityIds.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,7 +202,7 @@ public class ClientSynchronizationManager {
|
||||
* @param id The id that was destroyed
|
||||
*/
|
||||
public void addDeletedId(int id){
|
||||
this.deletedEntityIds.add(id);
|
||||
this.deletedEntityIds.put(id,1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,7 +211,17 @@ public class ClientSynchronizationManager {
|
||||
* @return true if it has been deleted, false otherwise
|
||||
*/
|
||||
public boolean isDeleted(int entityId){
|
||||
return this.deletedEntityIds.contains(entityId);
|
||||
return this.deletedEntityIds.containsKey(entityId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejects a deleted key (ie if server tells us to create a deleted entity again)
|
||||
* @param entityId The entity id to un-delete
|
||||
*/
|
||||
public void ejectDeletedKey(int entityId){
|
||||
if(this.deletedEntityIds.containsKey(entityId)){
|
||||
this.deletedEntityIds.remove(entityId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -5,6 +5,7 @@ import org.joml.Vector3d;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.server.ai.AI;
|
||||
import electrosphere.server.ai.blackboard.Blackboard;
|
||||
import electrosphere.server.ai.blackboard.BlackboardKeys;
|
||||
import electrosphere.server.ai.nodes.AITreeNode;
|
||||
@ -104,6 +105,7 @@ public class PathfindingNode implements AITreeNode {
|
||||
//check if the path has been found
|
||||
PathingProgressiveData pathingProgressiveData = PathfindingNode.getPathfindingData(blackboard);
|
||||
if(!pathingProgressiveData.isReady()){
|
||||
AI.getAI(entity).setStatus("Thinking about pathing");
|
||||
return AITreeNodeResult.RUNNING;
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,11 @@ public class TargetExploreNode implements AITreeNode {
|
||||
*/
|
||||
static final double OFFSET_DIST = 50;
|
||||
|
||||
/**
|
||||
* Offset applied to calculated height to align with voxel rasterization better
|
||||
*/
|
||||
static final double HEIGHT_OFFSET = 0.1f;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param targetKey The key to store the point under
|
||||
@ -50,7 +55,7 @@ public class TargetExploreNode implements AITreeNode {
|
||||
Vector3i voxelPos = ServerWorldData.convertRealToVoxelSpace(targetPos);
|
||||
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(targetPos);
|
||||
double height = realm.getServerWorldData().getServerTerrainManager().getElevation(chunkPos.x, chunkPos.z, voxelPos.x, voxelPos.z);
|
||||
targetPos.y = height;
|
||||
targetPos.y = height + HEIGHT_OFFSET;
|
||||
|
||||
//store
|
||||
blackboard.put(targetKey, targetPos);
|
||||
|
||||
@ -79,9 +79,7 @@ public class MoveToTree {
|
||||
|
||||
//not in range of target, keep moving towards it
|
||||
new SequenceNode(
|
||||
new PublishStatusNode("Thinking about pathing"),
|
||||
PathfindingNode.createPathEntity(targetKey),
|
||||
new PublishStatusNode("Moving"),
|
||||
new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT),
|
||||
new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD))
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user