performance improvements, profiler statements

This commit is contained in:
austin 2025-05-24 20:33:18 -04:00
parent 1ed791e6fe
commit 14680ef4c3
13 changed files with 282 additions and 96 deletions

View File

@ -52,6 +52,7 @@ public class ClientInteractionEngine {
DBody rigidBody = null;
Collidable collidable;
long categoryBit = Collidable.TYPE_OBJECT_BIT;
CollisionEngine.lockOde();
lock.lock();
interactables.add(rVal);
switch(physicsTemplate.getType()){
@ -167,6 +168,7 @@ public class ClientInteractionEngine {
}
}
lock.unlock();
CollisionEngine.unlockOde();
}
/**
@ -244,66 +246,66 @@ public class ClientInteractionEngine {
InteractionTargetMenu.setInteractionTargetString(text);
set = true;
}
if(!set){
target = Globals.clientState.clientSceneWrapper.getCollisionEngine().rayCast(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
if(target != null){
EntityType type = CommonEntityUtils.getEntityType(target);
if(type == null){
throw new Error("Entity does not have a type defined!");
}
switch(type){
case CREATURE: {
InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
set = true;
} break;
case ITEM: {
InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
set = true;
} break;
case FOLIAGE: {
InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
set = true;
} break;
default: {
//silently ignore
} break;
}
}
}
if(!set){
Vector3d collisionPosition = Globals.clientState.clientSceneWrapper.getCollisionEngine().rayCastPosition(centerPos, new Vector3d(eyePos).mul(-1), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
if(
collisionPosition != null &&
collisionPosition.distance(centerPos) < CollisionEngine.DEFAULT_INTERACT_DISTANCE &&
collisionPosition.x >= 0 && collisionPosition.y >= 0 && collisionPosition.z >= 0
){
//grab block at point
BlockChunkData blockChunkData = Globals.clientState.clientBlockManager.getChunkDataAtWorldPoint(Globals.clientState.clientWorldData.convertRealToWorldSpace(collisionPosition), 0);
if(blockChunkData != null){
Vector3i blockPos = ClientWorldData.convertRealToLocalBlockSpace(new Vector3d(collisionPosition).add(new Vector3d(eyePos).mul(-BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0f)));
if(!blockChunkData.isEmpty(blockPos.x, blockPos.y, blockPos.z)){
short type = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
String text = Globals.gameConfigCurrent.getBlockData().getTypeFromId(type).getName();
InteractionTargetMenu.setInteractionTargetString(text);
Globals.cursorState.hintShowBlockCursor();
Globals.cursorState.hintClampToExistingBlock();
set = true;
}
}
//if we didn't find a block type, try terrain
if(!set){
ChunkData chunkData = Globals.clientState.clientTerrainManager.getChunkDataAtWorldPoint(Globals.clientState.clientWorldData.convertRealToWorldSpace(collisionPosition), 0);
if(chunkData != null){
int voxelType = chunkData.getType(ClientWorldData.convertRealToVoxelSpace(new Vector3d(collisionPosition).add(new Vector3d(ServerTerrainChunk.VOXEL_SIZE / 2.0f))));
if(voxelType != ServerTerrainChunk.VOXEL_TYPE_AIR){
String text = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(voxelType).getName();
InteractionTargetMenu.setInteractionTargetString(text);
set = true;
}
}
}
}
}
// if(!set){
// target = Globals.clientState.clientSceneWrapper.getCollisionEngine().rayCast(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
// if(target != null){
// EntityType type = CommonEntityUtils.getEntityType(target);
// if(type == null){
// throw new Error("Entity does not have a type defined!");
// }
// switch(type){
// case CREATURE: {
// InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
// set = true;
// } break;
// case ITEM: {
// InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
// set = true;
// } break;
// case FOLIAGE: {
// InteractionTargetMenu.setInteractionTargetString(CommonEntityUtils.getEntitySubtype(target));
// set = true;
// } break;
// default: {
// //silently ignore
// } break;
// }
// }
// }
// if(!set){
// Vector3d collisionPosition = Globals.clientState.clientSceneWrapper.getCollisionEngine().rayCastPosition(centerPos, new Vector3d(eyePos).mul(-1), CollisionEngine.DEFAULT_INTERACT_DISTANCE);
// if(
// collisionPosition != null &&
// collisionPosition.distance(centerPos) < CollisionEngine.DEFAULT_INTERACT_DISTANCE &&
// collisionPosition.x >= 0 && collisionPosition.y >= 0 && collisionPosition.z >= 0
// ){
// //grab block at point
// BlockChunkData blockChunkData = Globals.clientState.clientBlockManager.getChunkDataAtWorldPoint(Globals.clientState.clientWorldData.convertRealToWorldSpace(collisionPosition), 0);
// if(blockChunkData != null){
// Vector3i blockPos = ClientWorldData.convertRealToLocalBlockSpace(new Vector3d(collisionPosition).add(new Vector3d(eyePos).mul(-BlockChunkData.BLOCK_SIZE_MULTIPLIER / 2.0f)));
// if(!blockChunkData.isEmpty(blockPos.x, blockPos.y, blockPos.z)){
// short type = blockChunkData.getType(blockPos.x, blockPos.y, blockPos.z);
// String text = Globals.gameConfigCurrent.getBlockData().getTypeFromId(type).getName();
// InteractionTargetMenu.setInteractionTargetString(text);
// Globals.cursorState.hintShowBlockCursor();
// Globals.cursorState.hintClampToExistingBlock();
// set = true;
// }
// }
// //if we didn't find a block type, try terrain
// if(!set){
// ChunkData chunkData = Globals.clientState.clientTerrainManager.getChunkDataAtWorldPoint(Globals.clientState.clientWorldData.convertRealToWorldSpace(collisionPosition), 0);
// if(chunkData != null){
// int voxelType = chunkData.getType(ClientWorldData.convertRealToVoxelSpace(new Vector3d(collisionPosition).add(new Vector3d(ServerTerrainChunk.VOXEL_SIZE / 2.0f))));
// if(voxelType != ServerTerrainChunk.VOXEL_TYPE_AIR){
// String text = Globals.gameConfigCurrent.getVoxelData().getTypeFromId(voxelType).getName();
// InteractionTargetMenu.setInteractionTargetString(text);
// set = true;
// }
// }
// }
// }
// }
if(!set){
InteractionTargetMenu.setInteractionTargetString("");
}

View File

@ -182,6 +182,11 @@ public class CollisionEngine {
* The base plane of the physics engine
*/
private DPlane basePlane = null;
/**
* Number of geometries
*/
private int geomCount = 0;
/**
* Constructor
@ -252,11 +257,16 @@ public class CollisionEngine {
}
}
/**
* Clear collidable impulse list
*/
public void clearCollidableImpulseLists(){
spaceLock.lock();
Globals.profiler.beginCpuSample("CollisionEngine.clearCollidableImpulseLists");
for(Collidable collidable : collidableList){
collidable.clear();
}
Globals.profiler.endCpuSample();
spaceLock.unlock();
}
@ -682,7 +692,7 @@ public class CollisionEngine {
Entity physicsEntity = collidable.getParent();
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
if(rigidBody != null){
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition());
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition()).add(this.floatingOrigin);
if(collected == 0){
newOrigin.set(currentBodyOffset);
} else {
@ -692,32 +702,32 @@ public class CollisionEngine {
}
collected++;
}
DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
if(geom != null){
if(geom instanceof DSpace space){
for(DGeom child : space.getGeoms()){
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(child.getPosition()).add(this.floatingOrigin);
if(collected == 0){
newOrigin.set(currentBodyOffset);
} else {
float percentExisting = collected / (float)(collected + 1);
float percentNew = 1.0f - percentExisting;
newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
}
collected++;
}
} else {
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin);
if(collected == 0){
newOrigin.set(currentBodyOffset);
} else {
float percentExisting = collected / (float)(collected + 1);
float percentNew = 1.0f - percentExisting;
newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
}
collected++;
}
}
// DGeom geom = PhysicsEntityUtils.getDGeom(physicsEntity);
// if(geom != null){
// if(geom instanceof DSpace space){
// for(DGeom child : space.getGeoms()){
// Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(child.getPosition()).add(this.floatingOrigin);
// if(collected == 0){
// newOrigin.set(currentBodyOffset);
// } else {
// float percentExisting = collected / (float)(collected + 1);
// float percentNew = 1.0f - percentExisting;
// newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
// }
// collected++;
// }
// } else {
// Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(geom.getPosition()).add(this.floatingOrigin);
// if(collected == 0){
// newOrigin.set(currentBodyOffset);
// } else {
// float percentExisting = collected / (float)(collected + 1);
// float percentNew = 1.0f - percentExisting;
// newOrigin = newOrigin.mul(percentExisting).add(currentBodyOffset.mul(percentNew));
// }
// collected++;
// }
// }
}
newOrigin = newOrigin.round();
Vector3d delta = new Vector3d(this.floatingOrigin);
@ -947,6 +957,7 @@ public class CollisionEngine {
while(geomIterator.hasNext()){
DGeom geom = geomIterator.next();
space.remove(geom);
this.geomCount--;
geom.destroy();
}
//destroy all joints
@ -972,6 +983,7 @@ public class CollisionEngine {
spaceLock.lock();
try {
geom.destroy();
this.geomCount--;
} catch (NullPointerException ex){
LoggerInterface.loggerEngine.ERROR(ex);
spaceLock.unlock();
@ -1076,6 +1088,7 @@ public class CollisionEngine {
DTriMesh rVal = OdeHelper.createTriMesh(this.space, data);
rVal.setTrimeshData(data);
rVal.setCategoryBits(categoryBits);
this.geomCount++;
spaceLock.unlock();
return rVal;
}
@ -1100,6 +1113,7 @@ public class CollisionEngine {
DTriMesh rVal = OdeHelper.createTriMesh(space, data);
rVal.setTrimeshData(data);
rVal.setCategoryBits(categoryBits);
this.geomCount++;
spaceLock.unlock();
return rVal;
}
@ -1113,6 +1127,7 @@ public class CollisionEngine {
spaceLock.lock();
DBox boxGeom = OdeHelper.createBox(space, dimensions.x, dimensions.y, dimensions.z);
boxGeom.setCategoryBits(categoryBits);
this.geomCount++;
spaceLock.unlock();
return boxGeom;
}
@ -1126,6 +1141,7 @@ public class CollisionEngine {
spaceLock.lock();
DCylinder cylinderGeom = OdeHelper.createCylinder(space, radius, length);
cylinderGeom.setCategoryBits(categoryBits);
this.geomCount++;
spaceLock.unlock();
return cylinderGeom;
}
@ -1139,6 +1155,7 @@ public class CollisionEngine {
spaceLock.lock();
DSphere sphereGeom = OdeHelper.createSphere(space, radius);
sphereGeom.setCategoryBits(categoryBits);
this.geomCount++;
spaceLock.unlock();
return sphereGeom;
}
@ -1153,6 +1170,7 @@ public class CollisionEngine {
spaceLock.lock();
DCapsule capsuleGeom = OdeHelper.createCapsule(space, radius, length);
capsuleGeom.setCategoryBits(categoryBits);
this.geomCount++;
spaceLock.unlock();
return capsuleGeom;
}
@ -1165,6 +1183,7 @@ public class CollisionEngine {
spaceLock.lock();
DSpace rVal = OdeHelper.createSimpleSpace();
this.space.add(rVal);
this.geomCount++;
spaceLock.unlock();
return rVal;
}
@ -1462,8 +1481,8 @@ public class CollisionEngine {
protected void destroyGeom(DGeom geom){
spaceLock.lock();
this.space.remove(geom);
geom.DESTRUCTOR();
geom.destroy();
this.geomCount--;
spaceLock.unlock();
}
@ -1501,6 +1520,7 @@ public class CollisionEngine {
"Geom Ptrs: " + this.geomPointerMap.size() + "\n" +
"Collidables: " + this.collidableList.size() + "\n" +
"Space geom count: " + this.space.getNumGeoms() + "\n" +
"Tracked geom count: " + this.geomCount + "\n" +
"Floating origin: " + this.floatingOrigin.x + "," + this.floatingOrigin.y + "," + this.floatingOrigin.z + "\n" +
""
;

View File

@ -123,7 +123,7 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
} else if(rayCastData.collidableTypeMask == null){
rayCastData.collisionPosition = new Vector3d(contact.geom.pos.get0(),contact.geom.pos.get1(),contact.geom.pos.get2());
} else {
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Collided with entity that is not defined in the rayCastData.bodyEntityMap! \"" + collidable1 + "\",\"" + collidable2 + "\""));
LoggerInterface.loggerEngine.ERROR(new Error("Collided with entity that is not defined in the rayCastData.bodyEntityMap! \"" + collidable1 + "\",\"" + collidable2 + "\""));
}
}
}
@ -133,7 +133,7 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
"body2: " + b2 + "\n" +
"collidable1: " + collidable1 + "\n" +
"collidable2: " + collidable2 + "\n";
LoggerInterface.loggerEngine.ERROR(new IllegalStateException(errorMessage));
LoggerInterface.loggerEngine.ERROR(new Error(errorMessage));
}
}
}

View File

@ -78,7 +78,7 @@ public class BlockChunkEntity {
}));
EntityCreationUtils.makeEntityDrawablePreexistingModel(solidsEnt, modelPath);
if(levelOfDetail == BlockChunkData.LOD_FULL_RES){
PhysicsEntityUtils.clientAttachMultiShapeTriGeomCollider(solidsEnt, data);
PhysicsEntityUtils.clientAttachTriGeomCollider(solidsEnt, data);
CollisionObjUtils.clientPositionCharacter(solidsEnt, new Vector3d(EntityUtils.getPosition(solidsEnt)), new Quaterniond());
} else {
EntityCreationUtils.bypassShadowPass(solidsEnt);
@ -182,7 +182,7 @@ public class BlockChunkEntity {
*/
public static void serverCreateBlockChunkEntity(Entity entity, BlockMeshData blockChunkData){
if(blockChunkData.getVertices().length > 0){
PhysicsEntityUtils.serverAttachMultiShapeTriGeomCollider(entity, blockChunkData);
PhysicsEntityUtils.serverAttachTriGeomCollider(entity, blockChunkData);
Realm realm = Globals.serverState.realmManager.getEntityRealm(entity);
DGeom terrainCollider = PhysicsEntityUtils.getDGeom(entity);
Vector3d entityPos = EntityUtils.getPosition(entity);

View File

@ -681,6 +681,109 @@ public class BlockMeshgen {
}
/**
* Contains the geom data for a single shape in the block mesh
*/
public static class BlockDims {
/**
* Width of the box
*/
private int width;
/**
* Height of the box
*/
private int height;
/**
* Length of the box
*/
private int length;
/**
* X coordinate of the box
*/
private int x;
/**
* Y coordinate of the box
*/
private int y;
/**
* Z coordinate of the box
*/
private int z;
/**
* Constructor
* @param width Width of the box
* @param height Height of the box
* @param length Length of the box
* @param x x coordinate of the box
* @param y y coordinate of the box
* @param z z coordinate of the box
*/
public BlockDims(int width, int height, int length, int x, int y, int z){
this.width = width;
this.height = height;
this.length = length;
this.x = x;
this.y = y;
this.z = z;
}
/**
* Gets the width of the box
* @return The width of the box
*/
public int getWidth(){
return width;
}
/**
* Gets the height of the box
* @return The height of the box
*/
public int getHeight(){
return height;
}
/**
* Gets the length of the box
* @return The length of the box
*/
public int getLength(){
return length;
}
/**
* Gets the x coordinate of the box
* @return The x coordinate
*/
public int getX(){
return x;
}
/**
* Gets the y coordinate of the box
* @return The y coordinate
*/
public int getY(){
return y;
}
/**
* Gets the z coordinate of the box
* @return The z coordinate
*/
public int getZ(){
return z;
}
}
/**
* The final rasterization data that is emitted
*/

View File

@ -420,7 +420,7 @@ public class Mesh {
* @param renderPipelineState The state of the render pipeline
*/
public void complexDraw(RenderPipelineState renderPipelineState, OpenGLState openGLState){
Globals.profiler.beginAggregateCpuSample("Mesh.complexDraw");
Globals.profiler.beginAggregateCpuSample("Mesh.complexDraw - total");
//bind vao off the rip
openGLState.glBindVertexArray(vertexArrayObject);
@ -517,6 +517,7 @@ public class Mesh {
boolean sentBones = false;
Globals.profiler.beginAggregateCpuSample("Bones");
if(renderPipelineState.getUseBones()){
//
//Handle bones
@ -545,9 +546,11 @@ public class Mesh {
openGLState.getActiveShader().setUniform(openGLState, currentUniform, new Matrix4d().identity());
}
}
Globals.profiler.endCpuSample();
if(renderPipelineState.getBufferStandardUniforms()){
Globals.profiler.beginAggregateCpuSample("Buffer standard uniforms");
//buffer model/view/proj matrices
try(MemoryStack stack = MemoryStack.stackPush()){
openGLState.getActiveShader().setUniform(openGLState, "model", parent.getModelMatrix());
@ -562,6 +565,7 @@ public class Mesh {
openGLState.glBindBufferBase(StandardUniformManager.STANDARD_UNIFORM_BUFFER_BIND_POINT, Globals.renderingEngine.getStandardUniformManager().getStandardUnifomSSBO());
}
Globals.renderingEngine.checkError();
Globals.profiler.endCpuSample();
}
if(renderPipelineState.getBufferNonStandardUniforms()){
@ -577,6 +581,7 @@ public class Mesh {
}
Globals.profiler.beginAggregateCpuSample("Mesh.complexDraw - Draw call");
if(renderPipelineState.getInstanced()){
if(renderPipelineState.getInstanceCount() < 1){
throw new Error("Failed to render instanced mesh with invalid instance count! " + this.getDebugData());
@ -597,6 +602,7 @@ public class Mesh {
Globals.renderingEngine.checkError();
}
Globals.profiler.endCpuSample();
Globals.profiler.endCpuSample();
}
/**

View File

@ -120,6 +120,7 @@ public class MainContentPipeline implements RenderPipeline {
}
}
}
renderPipelineState.setUseBones(false);
for(ModelAccumulatorData accumulator : this.drawTargetAccumulator.getCalls()){
Model model = Globals.assetManager.fetchModel(accumulator.getModelPath());
if(model != null){
@ -138,6 +139,7 @@ public class MainContentPipeline implements RenderPipeline {
}
}
}
renderPipelineState.setUseBones(true);
Globals.profiler.endCpuSample();
Globals.profiler.beginCpuSample("MainContentPipeline.render - Solids Foliage");
Globals.renderingEngine.getFoliagePipeline().render(openGLState, renderPipelineState);

View File

@ -140,6 +140,7 @@ public class ShadowMapPipeline implements RenderPipeline {
currentActor.draw(renderPipelineState,openGLState);
}
}
renderPipelineState.setUseBones(false);
for(ModelAccumulatorData accumulator : this.drawTargetAccumulator.getCalls()){
Model model = Globals.assetManager.fetchModel(accumulator.getModelPath());
if(model != null){

View File

@ -21,9 +21,11 @@ public class MainServerFunctions {
//
//Cleanup disconnected clients
Globals.profiler.beginCpuSample("MainServerFunctions.simulate - Cleanup connections");
if(Globals.serverState.server != null){
Globals.serverState.server.cleanupDeadConnections();
}
Globals.profiler.endCpuSample();
//
//Synchronous player message parsing\
@ -60,7 +62,9 @@ public class MainServerFunctions {
* Simulates server services
*/
private static void simulateServices(){
Globals.profiler.beginCpuSample("MainServerFunctions.simulateServices");
Globals.serverState.structureScanningService.simulate();
Globals.profiler.endCpuSample();
}
}

View File

@ -9,6 +9,7 @@ import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;
import electrosphere.data.entity.creature.ai.AITreeData;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.ai.services.NearbyEntityService;
@ -76,6 +77,7 @@ public class AIManager {
* Simulates all AIs currently available
*/
public void simulate(){
Globals.profiler.beginCpuSample("AIManager.simulate");
lock.lock();
//exec the services
this.execServices();
@ -91,6 +93,7 @@ public class AIManager {
}
}
lock.unlock();
Globals.profiler.endCpuSample();
}
/**

View File

@ -207,7 +207,9 @@ public class ServerDataCell {
List<String> tags = oldCell.getScene().extractTags(entity);
oldCell.getScene().deregisterEntity(entity);
newCell.getScene().registerEntity(entity);
newCell.getScene().registerEntityToTags(entity, tags);
if(tags != null){
newCell.getScene().registerEntityToTags(entity, tags);
}
//update entity data cell mapper
Globals.serverState.entityDataCellMapper.updateEntityCell(entity, newCell);
//send the entity to new players that should care about it

View File

@ -24,6 +24,11 @@ public class MacroSimulation {
* Iterates the macro simulation
*/
public static void simulate(Realm realm){
Globals.profiler.beginCpuSample("MacroSimulation.simulate");
//
//simulate characters
Globals.profiler.beginCpuSample("MacroSimulation.simulate - characters");
List<Character> characters = Globals.serverState.characterService.getAllCharacters();
if(characters != null && characters.size() > 0){
for(Character character : Globals.serverState.characterService.getAllCharacters()){
@ -38,10 +43,17 @@ public class MacroSimulation {
}
}
}
Globals.profiler.endCpuSample();
//
//simulate towns
Globals.profiler.beginCpuSample("MacroSimulation.simulate - towns");
List<Town> towns = realm.getMacroData().getTowns();
for(Town town : towns){
TownSimulator.simualte(town);
}
Globals.profiler.endCpuSample();
Globals.profiler.endCpuSample();
}
/**

View File

@ -8,6 +8,7 @@ import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.lod.ServerLODComponent;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.entity.poseactor.PoseActor;
@ -40,6 +41,11 @@ public class MicroSimulation {
Set<Entity> poseableEntities = dataCell.getScene().getEntitiesWithTag(EntityTags.POSEABLE);
if(poseableEntities != null){
for(Entity currentEntity : poseableEntities){
if(ServerLODComponent.hasServerLODComponent(currentEntity)){
if(ServerLODComponent.getServerLODComponent(currentEntity).getLodLevel() == ServerLODComponent.LOW_RES){
continue;
}
}
//fetch actor
PoseActor currentPoseActor = EntityUtils.getPoseActor(currentEntity);
//increment animations
@ -48,35 +54,60 @@ public class MicroSimulation {
}
}
}
//
//make items play idle animation
for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){
ItemUtils.updateItemPoseActorAnimation(item);
for(Entity itemEnt : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){
if(ServerLODComponent.hasServerLODComponent(itemEnt)){
if(ServerLODComponent.getServerLODComponent(itemEnt).getLodLevel() == ServerLODComponent.LOW_RES){
continue;
}
}
ItemUtils.updateItemPoseActorAnimation(itemEnt);
}
//
//simulate behavior trees
if(dataCell.getScene().getBehaviorTrees().size() > 0){
dataCell.getScene().simulateBehaviorTrees((float)Globals.engineState.timekeeper.getSimFrameTime());
}
//update attached entity positions
//!!This must come after simulating behavior trees!!
//if it does not come after queueing animations, the attach positions might not represent the animation of the parent
Globals.profiler.beginCpuSample("MicroSimulation - attached entity positions");
AttachUtils.serverUpdateAttachedEntityPositions(dataCell);
Globals.profiler.endCpuSample();
//
//sum collidable impulses
Globals.profiler.beginCpuSample("MicroSimulation - collidables");
Set<Entity> collidables = dataCell.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE);
for(Entity collidable : collidables){
if(ServerCollidableTree.hasServerCollidableTree(collidable)){
ServerCollidableTree.getServerCollidableTree(collidable).simulate((float)Globals.engineState.timekeeper.getSimFrameTime());
}
}
Globals.profiler.endCpuSample();
//
//update actor transform caches
Globals.profiler.beginCpuSample("MicroSimulation - poseables");
poseableEntities = dataCell.getScene().getEntitiesWithTag(EntityTags.POSEABLE);
if(poseableEntities != null){
for(Entity currentEntity : dataCell.getScene().getEntitiesWithTag(EntityTags.POSEABLE)){
if(ServerLODComponent.hasServerLODComponent(currentEntity)){
if(ServerLODComponent.getServerLODComponent(currentEntity).getLodLevel() == ServerLODComponent.LOW_RES){
continue;
}
}
//fetch actor
PoseActor currentPoseActor = EntityUtils.getPoseActor(currentEntity);
currentPoseActor.updateTransformCache();
}
}
Globals.profiler.endCpuSample();
}
Globals.profiler.endCpuSample();
}