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
|
New AI behaviors
|
||||||
- Will explore for resources if local ones aren't available
|
- Will explore for resources if local ones aren't available
|
||||||
Async pathfinding
|
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){
|
public static void destroyCollidableTemplate(Entity rVal){
|
||||||
lock.lock();
|
lock.lock();
|
||||||
CollisionEngine interactionEngine = Globals.clientSceneWrapper.getInteractionEngine();
|
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();
|
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 {
|
public class ClientSceneWrapper {
|
||||||
|
|
||||||
//entity id translation between server/client
|
/**
|
||||||
|
* Translates client entity IDs to server IDs
|
||||||
|
*/
|
||||||
Map<Integer,Integer> clientToServerIdMap = new HashMap<Integer,Integer>();
|
Map<Integer,Integer> clientToServerIdMap = new HashMap<Integer,Integer>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates server entity IDs to client IDs
|
||||||
|
*/
|
||||||
Map<Integer,Integer> serverToClientIdMap = new HashMap<Integer,Integer>();
|
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>();
|
Map<Integer,Boolean> deletedServerIds = new HashMap<Integer,Boolean>();
|
||||||
|
|
||||||
//The scene backing the wrapper
|
/**
|
||||||
|
* The scene backing the wrapper
|
||||||
|
*/
|
||||||
Scene scene;
|
Scene scene;
|
||||||
|
|
||||||
//The engine used to back physics collision checks in client
|
/**
|
||||||
|
* The engine used to back physics collision checks in client
|
||||||
|
*/
|
||||||
CollisionEngine collisionEngine;
|
CollisionEngine collisionEngine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,7 +59,9 @@ public class ClientSceneWrapper {
|
|||||||
*/
|
*/
|
||||||
CollisionEngine interactionEngine;
|
CollisionEngine interactionEngine;
|
||||||
|
|
||||||
//The hitbox manager
|
/**
|
||||||
|
* The hitbox manager
|
||||||
|
*/
|
||||||
HitboxManager hitboxManager;
|
HitboxManager hitboxManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,6 +94,7 @@ public class ClientSceneWrapper {
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
clientToServerIdMap.put(clientId, serverId);
|
clientToServerIdMap.put(clientId, serverId);
|
||||||
serverToClientIdMap.put(serverId, clientId);
|
serverToClientIdMap.put(serverId, clientId);
|
||||||
|
Globals.clientSynchronizationManager.ejectDeletedKey(serverId);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package electrosphere.client.ui.menu.debug;
|
|||||||
import org.joml.Vector3i;
|
import org.joml.Vector3i;
|
||||||
|
|
||||||
import electrosphere.client.entity.camera.CameraEntityUtils;
|
import electrosphere.client.entity.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.client.interact.ClientInteractionEngine;
|
||||||
import electrosphere.client.terrain.cache.ChunkData;
|
import electrosphere.client.terrain.cache.ChunkData;
|
||||||
import electrosphere.client.terrain.cells.DrawCell;
|
import electrosphere.client.terrain.cells.DrawCell;
|
||||||
import electrosphere.client.terrain.foliage.FoliageCell;
|
import electrosphere.client.terrain.foliage.FoliageCell;
|
||||||
@ -83,7 +84,8 @@ public class ImGuiClientServices {
|
|||||||
|
|
||||||
|
|
||||||
if(ImGui.collapsingHeader("Interaction Engine")){
|
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")){
|
if(ImGui.button("Network Monitor")){
|
||||||
ImGuiNetworkMonitor.netMonitorWindow.setOpen(true);
|
ImGuiNetworkMonitor.netMonitorWindow.setOpen(true);
|
||||||
}
|
}
|
||||||
if(ImGui.button("Client Draw Cell Utils")){
|
if(ImGui.button("Client Services")){
|
||||||
ImGuiClientServices.clientServicesWindow.setOpen(true);
|
ImGuiClientServices.clientServicesWindow.setOpen(true);
|
||||||
}
|
}
|
||||||
//close button
|
//close button
|
||||||
|
|||||||
@ -613,6 +613,7 @@ public class CollisionEngine {
|
|||||||
public void deregisterCollisionObject(DBody body, Collidable collidable){
|
public void deregisterCollisionObject(DBody body, Collidable collidable){
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
bodyPointerMap.remove(body);
|
bodyPointerMap.remove(body);
|
||||||
|
bodies.remove(body);
|
||||||
collidableList.remove(collidable);
|
collidableList.remove(collidable);
|
||||||
spaceLock.unlock();
|
spaceLock.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -728,7 +728,9 @@ public class Globals {
|
|||||||
Globals.clientSynchronizationManager = new ClientSynchronizationManager();
|
Globals.clientSynchronizationManager = new ClientSynchronizationManager();
|
||||||
Globals.server = null;
|
Globals.server = null;
|
||||||
Globals.serverSynchronizationManager = new ServerSynchronizationManager();
|
Globals.serverSynchronizationManager = new ServerSynchronizationManager();
|
||||||
Globals.aiManager.shutdown();
|
if(Globals.aiManager != null){
|
||||||
|
Globals.aiManager.shutdown();
|
||||||
|
}
|
||||||
if(Globals.realmManager != null){
|
if(Globals.realmManager != null){
|
||||||
Globals.realmManager.reset();
|
Globals.realmManager.reset();
|
||||||
}
|
}
|
||||||
@ -740,7 +742,9 @@ public class Globals {
|
|||||||
*/
|
*/
|
||||||
public static void resetGlobals(){
|
public static void resetGlobals(){
|
||||||
Globals.unloadScene();
|
Globals.unloadScene();
|
||||||
Globals.aiManager.shutdown();
|
if(Globals.aiManager != null){
|
||||||
|
Globals.aiManager.shutdown();
|
||||||
|
}
|
||||||
//
|
//
|
||||||
//Actual globals to destroy
|
//Actual globals to destroy
|
||||||
Globals.assetManager = null;
|
Globals.assetManager = null;
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import java.util.HashMap;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
@ -42,6 +43,11 @@ public class ClientSynchronizationManager {
|
|||||||
*/
|
*/
|
||||||
static final int MESSAGE_BOUNCE_WARNING_COUNT = 100;
|
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
|
* 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
|
* 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
|
* 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
|
//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);
|
messageBounceCount.remove(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +188,13 @@ public class ClientSynchronizationManager {
|
|||||||
messages.remove(message);
|
messages.remove(message);
|
||||||
Globals.clientConnection.release(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
|
* @param id The id that was destroyed
|
||||||
*/
|
*/
|
||||||
public void addDeletedId(int id){
|
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
|
* @return true if it has been deleted, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean isDeleted(int entityId){
|
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.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.server.ai.AI;
|
||||||
import electrosphere.server.ai.blackboard.Blackboard;
|
import electrosphere.server.ai.blackboard.Blackboard;
|
||||||
import electrosphere.server.ai.blackboard.BlackboardKeys;
|
import electrosphere.server.ai.blackboard.BlackboardKeys;
|
||||||
import electrosphere.server.ai.nodes.AITreeNode;
|
import electrosphere.server.ai.nodes.AITreeNode;
|
||||||
@ -104,6 +105,7 @@ public class PathfindingNode implements AITreeNode {
|
|||||||
//check if the path has been found
|
//check if the path has been found
|
||||||
PathingProgressiveData pathingProgressiveData = PathfindingNode.getPathfindingData(blackboard);
|
PathingProgressiveData pathingProgressiveData = PathfindingNode.getPathfindingData(blackboard);
|
||||||
if(!pathingProgressiveData.isReady()){
|
if(!pathingProgressiveData.isReady()){
|
||||||
|
AI.getAI(entity).setStatus("Thinking about pathing");
|
||||||
return AITreeNodeResult.RUNNING;
|
return AITreeNodeResult.RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,11 @@ public class TargetExploreNode implements AITreeNode {
|
|||||||
*/
|
*/
|
||||||
static final double OFFSET_DIST = 50;
|
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
|
* constructor
|
||||||
* @param targetKey The key to store the point under
|
* @param targetKey The key to store the point under
|
||||||
@ -50,7 +55,7 @@ public class TargetExploreNode implements AITreeNode {
|
|||||||
Vector3i voxelPos = ServerWorldData.convertRealToVoxelSpace(targetPos);
|
Vector3i voxelPos = ServerWorldData.convertRealToVoxelSpace(targetPos);
|
||||||
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(targetPos);
|
Vector3i chunkPos = ServerWorldData.convertRealToChunkSpace(targetPos);
|
||||||
double height = realm.getServerWorldData().getServerTerrainManager().getElevation(chunkPos.x, chunkPos.z, voxelPos.x, voxelPos.z);
|
double height = realm.getServerWorldData().getServerTerrainManager().getElevation(chunkPos.x, chunkPos.z, voxelPos.x, voxelPos.z);
|
||||||
targetPos.y = height;
|
targetPos.y = height + HEIGHT_OFFSET;
|
||||||
|
|
||||||
//store
|
//store
|
||||||
blackboard.put(targetKey, targetPos);
|
blackboard.put(targetKey, targetPos);
|
||||||
|
|||||||
@ -79,9 +79,7 @@ public class MoveToTree {
|
|||||||
|
|
||||||
//not in range of target, keep moving towards it
|
//not in range of target, keep moving towards it
|
||||||
new SequenceNode(
|
new SequenceNode(
|
||||||
new PublishStatusNode("Thinking about pathing"),
|
|
||||||
PathfindingNode.createPathEntity(targetKey),
|
PathfindingNode.createPathEntity(targetKey),
|
||||||
new PublishStatusNode("Moving"),
|
|
||||||
new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT),
|
new FaceTargetNode(BlackboardKeys.PATHFINDING_POINT),
|
||||||
new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD))
|
new RunnerNode(new MoveStartNode(MovementRelativeFacing.FORWARD))
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user