Remotery + extensive profiler usage
This commit is contained in:
parent
c9b48a2ea5
commit
b711111589
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -15,7 +15,7 @@
|
||||
"name": "Launch Main",
|
||||
"request": "launch",
|
||||
"mainClass": "electrosphere.engine.Main",
|
||||
"vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"",
|
||||
"vmArgs": "-Xmx2G -Xms100m -XX:+UseZGC -XX:+UseDynamicNumberOfGCThreads -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"",
|
||||
"projectName": "Renderer"
|
||||
},
|
||||
{
|
||||
@ -26,7 +26,7 @@
|
||||
"env": {
|
||||
"ALSOFT_LOGLEVEL": 4,
|
||||
},
|
||||
"vmArgs": "-Xmx2G -Xms100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"",
|
||||
"vmArgs": "-Xmx2G -Xms100m -XX:+UseZGC -XX:+UseDynamicNumberOfGCThreads -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"/tmp\"",
|
||||
"projectName": "Renderer"
|
||||
},
|
||||
{
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#maven.buildNumber.plugin properties file
|
||||
#Sat Mar 23 16:53:49 EDT 2024
|
||||
buildNumber=80
|
||||
#Sat Mar 23 19:48:52 EDT 2024
|
||||
buildNumber=82
|
||||
|
||||
@ -185,6 +185,8 @@ Physics-controlled objects system
|
||||
|
||||
# TODO
|
||||
|
||||
Clean up main method/class
|
||||
- Include Remotery library
|
||||
|
||||
Level loading/saving + Basic Editor
|
||||
- Spin up voxel level (think arena mode)
|
||||
@ -193,6 +195,9 @@ Level loading/saving + Basic Editor
|
||||
- Menu of types of entities to spawn
|
||||
- Button to spawn them at cursor
|
||||
|
||||
Revisit first attempt at instancing (its really laggy lol)
|
||||
- Maybe have draw call happen on top level entity and immediately queue all children recursively
|
||||
|
||||
Shader library system
|
||||
- Abiltiy to include the shader library in individual files (ie implement #include)
|
||||
|
||||
@ -229,9 +234,6 @@ Light Manager
|
||||
- Eventually support spot lights?
|
||||
- Point shadows ???
|
||||
|
||||
Clean up main method/class
|
||||
- Include Remotery library
|
||||
|
||||
gltf Support
|
||||
- Fix bad data with human mesh textures not mapping
|
||||
- Texture loading from gltf file
|
||||
|
||||
15
pom.xml
15
pom.xml
@ -10,6 +10,7 @@
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<lwjgl.version>3.2.3</lwjgl.version>
|
||||
<lwjgl.remotery.version>3.3.3</lwjgl.remotery.version>
|
||||
<joml.version>1.9.19</joml.version>
|
||||
<recast.version>1.5.7</recast.version>
|
||||
<imgui.version>1.86.11</imgui.version>
|
||||
@ -110,6 +111,20 @@
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
</dependency>
|
||||
|
||||
<!--Remotery-->
|
||||
<!--License: Apache 2.0-->
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-remotery</artifactId>
|
||||
<version>${lwjgl.remotery.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-remotery</artifactId>
|
||||
<version>${lwjgl.remotery.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
</dependency>
|
||||
|
||||
<!--JOML-->
|
||||
<!--License: MIT-->
|
||||
<dependency>
|
||||
|
||||
@ -142,12 +142,14 @@ public class AudioEngine {
|
||||
* Updates the orientation of the listener based on the global player camera
|
||||
*/
|
||||
private void updateListener(){
|
||||
if(Globals.playerCamera != null){
|
||||
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
|
||||
Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).mul(-1);
|
||||
Vector3f cameraUp = new Vector3f(0,1,0);
|
||||
listener.setPosition(cameraPos);
|
||||
listener.setOrientation(cameraEye, cameraUp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the audio engine
|
||||
|
||||
@ -5,6 +5,7 @@ import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
@ -34,7 +35,7 @@ public class VirtualAudioSourceManager {
|
||||
List<VirtualAudioSourceCategory> categories = new LinkedList<VirtualAudioSourceCategory>();
|
||||
|
||||
//The list of all virtual sources
|
||||
List<VirtualAudioSource> virtualSourceQueue = new LinkedList<VirtualAudioSource>();
|
||||
List<VirtualAudioSource> virtualSourceQueue = new CopyOnWriteArrayList<VirtualAudioSource>();
|
||||
|
||||
//the map of virtual source to active source for all active sources
|
||||
Map<VirtualAudioSource,AudioSource> virtualActiveMap = new HashMap<VirtualAudioSource,AudioSource>();
|
||||
@ -150,6 +151,7 @@ public class VirtualAudioSourceManager {
|
||||
} else {
|
||||
realSource = AudioUtils.playAudioAtLocation(source.filePath, new Vector3f((float)source.position.x,(float)source.position.y,(float)source.position.z),source.loops);
|
||||
}
|
||||
if(realSource != null){
|
||||
source.setFadeRate(category.fadeInRate);
|
||||
realSource.setGain(source.gain);
|
||||
realSource.setOffset(source.totalTimePlayed);
|
||||
@ -158,6 +160,7 @@ public class VirtualAudioSourceManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the queue of all currently active sources
|
||||
|
||||
@ -239,9 +239,8 @@ public class FluidCellManager {
|
||||
|
||||
/**
|
||||
* Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly
|
||||
* @param position The position of the player entity on current frame
|
||||
*/
|
||||
public void calculateDeltas(Vector3d position){
|
||||
private void calculateDeltas(){
|
||||
//check if any not requested cells no longer need to be requested
|
||||
clearOutOfBoundsCells();
|
||||
//check if any cells should be added
|
||||
@ -320,6 +319,7 @@ public class FluidCellManager {
|
||||
* Updates cells that need updating in this manager
|
||||
*/
|
||||
public void update(){
|
||||
calculateDeltas();
|
||||
if(update){
|
||||
if(containsUnrequestedCell() && !containsUndrawableCell()){
|
||||
updateUnrequestedCell();
|
||||
|
||||
@ -144,11 +144,13 @@ public class ClientFluidManager {
|
||||
* Pushes all fluid data in queue to the gpu and registers the resulting models
|
||||
*/
|
||||
public static void generateFluidChunkGeometry(){
|
||||
Globals.profiler.beginCpuSample("generateFluidChunkGeometry");
|
||||
for(FluidChunkGenQueueItem queueItem : fluidChunkGenerationQueue){
|
||||
Model fluidModel = FluidChunkModelGeneration.generateFluidModel(queueItem.getData());
|
||||
Globals.assetManager.registerModelToSpecificString(fluidModel, queueItem.getPromisedHash());
|
||||
}
|
||||
fluidChunkGenerationQueue.clear();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -134,6 +134,7 @@ public class ClientFoliageManager {
|
||||
* Updates all grass entities
|
||||
*/
|
||||
public void update(){
|
||||
Globals.profiler.beginCpuSample("ClientFoliageManager.update");
|
||||
if(ready){
|
||||
//for each invalid cell, see if can be revalidated
|
||||
for(String key : locationEvaluationCooldownMap.keySet()){
|
||||
@ -161,6 +162,7 @@ public class ClientFoliageManager {
|
||||
//invalidate foliage cells that have had their voxel changed
|
||||
invalidateModifiedPositions();
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package electrosphere.client.instancing;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
@ -18,12 +20,18 @@ public class InstanceUpdater {
|
||||
* Updates all instanced actors to have priority based on distance from camera
|
||||
*/
|
||||
public static void updateInstancedActorPriority(){
|
||||
Globals.profiler.beginCpuSample("updateInstancedActorPriority");
|
||||
if(Globals.playerCamera != null){
|
||||
Vector3d eyePosition = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||
for(Entity entity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED)){
|
||||
Set<Entity> instancedEntities = Globals.clientScene.getEntitiesWithTag(EntityTags.DRAW_INSTANCED);
|
||||
for(Entity entity : instancedEntities){
|
||||
//set priority equal to distance
|
||||
Vector3d entityPosition = EntityUtils.getPosition(entity);
|
||||
InstancedActor.getInstancedActor(entity).setPriority((int)entityPosition.distance(eyePosition));
|
||||
int priority = (int)entityPosition.distance(eyePosition);
|
||||
InstancedActor.getInstancedActor(entity).setPriority(priority);
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package electrosphere.client.scene;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@ -113,13 +114,19 @@ public class ClientSceneWrapper {
|
||||
* Destroys all entities outside simulation range
|
||||
*/
|
||||
public void destroyEntitiesOutsideSimRange(){
|
||||
double cullRadius = Globals.drawCellManager.getDrawRadius() + ServerTerrainChunk.CHUNK_DIMENSION;
|
||||
for(Entity entity : scene.getEntityList()){
|
||||
Vector3d position = EntityUtils.getPosition(entity);
|
||||
if(Globals.playerEntity != null && EntityUtils.getPosition(Globals.playerEntity).distance(position) > cullRadius){
|
||||
EntityUtils.cleanUpEntity(entity);
|
||||
}
|
||||
}
|
||||
Globals.profiler.beginCpuSample("destroyEntitiesOutsideSimRange");
|
||||
// if(Globals.drawCellManager != null && Globals.playerEntity != null){
|
||||
// double cullRadius = Globals.drawCellManager.getDrawRadius() + ServerTerrainChunk.CHUNK_DIMENSION;
|
||||
// Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
// List<Entity> entityList = scene.getEntityList();
|
||||
// for(Entity entity : entityList){
|
||||
// Vector3d position = EntityUtils.getPosition(entity);
|
||||
// if(playerPosition.distance(position) > cullRadius){
|
||||
// EntityUtils.cleanUpEntity(entity);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,86 +0,0 @@
|
||||
package electrosphere.client.sim;
|
||||
|
||||
import electrosphere.client.fluid.manager.ClientFluidManager;
|
||||
import electrosphere.client.instancing.InstanceUpdater;
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.EntityUtils;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class ClientFunctions {
|
||||
|
||||
static Vector3d oldPlayerCharacterPosition = new Vector3d();
|
||||
static Vector3d newPlayerCharacterPosition = new Vector3d();
|
||||
|
||||
public static void runBeforeSimulationFunctions(){
|
||||
//cell tracking values
|
||||
if(Globals.playerEntity != null){
|
||||
oldPlayerCharacterPosition = new Vector3d(EntityUtils.getPosition(Globals.playerEntity));
|
||||
}
|
||||
//process all server synchronization messages
|
||||
Globals.clientSynchronizationManager.processMessages();
|
||||
}
|
||||
|
||||
public static void runClientFunctions(){
|
||||
ClientTerrainManager.generateTerrainChunkGeometry();
|
||||
ClientFluidManager.generateFluidChunkGeometry();
|
||||
updateSkyboxPos();
|
||||
Globals.clientSceneWrapper.destroyEntitiesOutsideSimRange();
|
||||
InstanceUpdater.updateInstancedActorPriority();
|
||||
Globals.cameraHandler.updateGlobalCamera();
|
||||
// updateCellManager();
|
||||
}
|
||||
|
||||
static void updateSkyboxPos(){
|
||||
if(Globals.skybox != null && Globals.playerEntity != null){
|
||||
// Vector3f skyboxPos = EntityUtils.getPosition(Globals.skybox);
|
||||
//
|
||||
// Vector3f playerCameraPos = EntityUtils.getPosition(Globals.playerCamera);
|
||||
// if(skyboxPos != null && playerCameraPos != null){
|
||||
// skyboxPos.set(playerCameraPos);
|
||||
// }
|
||||
EntityUtils.getPosition(Globals.skybox).set(EntityUtils.getPosition(Globals.playerEntity));
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadTerrain(){
|
||||
if(Globals.clientTerrainManager != null){
|
||||
Globals.clientTerrainManager.handleMessages();
|
||||
updateTerrainCellManager();
|
||||
}
|
||||
if(Globals.clientFluidManager != null){
|
||||
Globals.clientFluidManager.handleMessages();
|
||||
updateFluidCellManager();
|
||||
}
|
||||
}
|
||||
|
||||
static void updateTerrainCellManager(){
|
||||
///
|
||||
/// C L I E N T C E L L M A N A G E R
|
||||
///
|
||||
if(Globals.drawCellManager != null && Globals.clientWorldData != null){
|
||||
if(Globals.playerEntity != null){
|
||||
newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
}
|
||||
//Cell manager do your things
|
||||
Globals.drawCellManager.calculateDeltas(newPlayerCharacterPosition);
|
||||
Globals.drawCellManager.update();
|
||||
}
|
||||
}
|
||||
|
||||
static void updateFluidCellManager(){
|
||||
//fluid work
|
||||
if(Globals.fluidCellManager != null && Globals.clientWorldData != null){
|
||||
if(Globals.playerEntity != null){
|
||||
newPlayerCharacterPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
}
|
||||
Globals.fluidCellManager.calculateDeltas(newPlayerCharacterPosition);
|
||||
Globals.fluidCellManager.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,11 @@
|
||||
package electrosphere.client.sim;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.client.fluid.manager.ClientFluidManager;
|
||||
import electrosphere.client.instancing.InstanceUpdater;
|
||||
import electrosphere.client.targeting.crosshair.Crosshair;
|
||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
import electrosphere.collision.PhysicsUtils;
|
||||
import electrosphere.engine.Globals;
|
||||
@ -17,35 +22,66 @@ import electrosphere.renderer.actor.Actor;
|
||||
|
||||
public class ClientSimulation {
|
||||
|
||||
//if true, is ready to simulate
|
||||
boolean isReady = false;
|
||||
|
||||
//if true, should load terrain
|
||||
boolean loadTerrain = false;
|
||||
|
||||
//used for tracking different in player position between frames (principally for draw cell manager)
|
||||
Vector3d newPlayerCharacterPosition = new Vector3d();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClientSimulation(){
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main simulation function
|
||||
*/
|
||||
public void simulate(){
|
||||
Globals.profiler.beginCpuSample("simulate");
|
||||
|
||||
//load terrain
|
||||
if(isLoadingTerrain()){
|
||||
loadTerrain();
|
||||
}
|
||||
|
||||
//process all server synchronization messages
|
||||
Globals.profiler.beginCpuSample("clientSynchronizationManager.processMessages");
|
||||
Globals.clientSynchronizationManager.processMessages();
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
//simulate bullet physics engine step
|
||||
Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
||||
Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms();
|
||||
//update actor animations
|
||||
Globals.profiler.beginCpuSample("update actor animations");
|
||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||
Actor currentActor = EntityUtils.getActor(currentEntity);
|
||||
if(currentActor.isPlayingAnimation()){
|
||||
currentActor.incrementAnimationTime((float)Globals.timekeeper.getSimFrameTime());
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
//make items play idle animation
|
||||
Globals.profiler.beginCpuSample("item animations");
|
||||
for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
||||
ItemUtils.updateItemActorAnimation(item);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
//particle state updates
|
||||
Globals.profiler.beginCpuSample("particle state updates");
|
||||
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
||||
ParticleUtils.makeParticleBillboardFaceCamera(particle);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
//update attached entity positions
|
||||
AttachUtils.clientUpdateAttachedEntityPositions();
|
||||
//update hitbox positions
|
||||
Globals.profiler.beginCpuSample("Hitbox updates");
|
||||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
||||
HitboxUtils.clientUpdatePosition(currentHitbox);
|
||||
}
|
||||
@ -55,11 +91,14 @@ public class ClientSimulation {
|
||||
HitboxUtils.clientCollideEntities(currentHitbox);
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
//update audio engine
|
||||
Globals.profiler.beginCpuSample("audio engine update");
|
||||
if(Globals.audioEngine!=null){
|
||||
Globals.audioEngine.update();
|
||||
Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime());
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
//update foliage
|
||||
Globals.clientFoliageManager.update();
|
||||
//tally collidables and offset position accordingly
|
||||
@ -68,16 +107,88 @@ public class ClientSimulation {
|
||||
// tree.simulate(Main.deltaFrames);
|
||||
// }
|
||||
//targeting crosshair
|
||||
Globals.profiler.beginCpuSample("crosshair update");
|
||||
Crosshair.checkTargetable();
|
||||
Crosshair.updateTargetCrosshairPosition();
|
||||
Globals.profiler.endCpuSample();
|
||||
//simulate behavior trees
|
||||
Globals.clientSceneWrapper.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
||||
//sum collidable impulses
|
||||
Globals.profiler.beginCpuSample("collidable logic");
|
||||
for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime());
|
||||
}
|
||||
//clear collidable impulse lists
|
||||
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
//wrap up functions
|
||||
runClientFunctions();
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
public void runClientFunctions(){
|
||||
Globals.profiler.beginCpuSample("client functions");
|
||||
ClientTerrainManager.generateTerrainChunkGeometry();
|
||||
ClientFluidManager.generateFluidChunkGeometry();
|
||||
updateSkyboxPos();
|
||||
Globals.clientSceneWrapper.destroyEntitiesOutsideSimRange();
|
||||
InstanceUpdater.updateInstancedActorPriority();
|
||||
Globals.cameraHandler.updateGlobalCamera();
|
||||
// updateCellManager();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the skybox position to center on the player
|
||||
*/
|
||||
void updateSkyboxPos(){
|
||||
Globals.profiler.beginCpuSample("updateSkyboxPos");
|
||||
if(Globals.skybox != null && Globals.playerEntity != null){
|
||||
EntityUtils.getPosition(Globals.skybox).set(EntityUtils.getPosition(Globals.playerEntity));
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads terrain that is in queue
|
||||
*/
|
||||
public void loadTerrain(){
|
||||
Globals.profiler.beginCpuSample("load terrain");
|
||||
if(Globals.clientTerrainManager != null){
|
||||
Globals.clientTerrainManager.handleMessages();
|
||||
updateTerrainCellManager();
|
||||
}
|
||||
if(Globals.clientFluidManager != null){
|
||||
Globals.clientFluidManager.handleMessages();
|
||||
updateFluidCellManager();
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the terrain cell manager (specifically position handling)
|
||||
*/
|
||||
void updateTerrainCellManager(){
|
||||
///
|
||||
/// C L I E N T C E L L M A N A G E R
|
||||
///
|
||||
if(Globals.drawCellManager != null && Globals.clientWorldData != null){
|
||||
//Cell manager do your things
|
||||
Globals.drawCellManager.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the fluid cell manager (specifically position handling)
|
||||
*/
|
||||
void updateFluidCellManager(){
|
||||
//fluid work
|
||||
if(Globals.fluidCellManager != null && Globals.clientWorldData != null){
|
||||
Globals.fluidCellManager.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -260,9 +260,8 @@ public class DrawCellManager {
|
||||
|
||||
/**
|
||||
* Calculates whether the position of the player has changed and if so, invalidates and cleans up cells accordingly
|
||||
* @param position The position of the player entity on current frame
|
||||
*/
|
||||
public void calculateDeltas(Vector3d position){
|
||||
private void calculateDeltas(){
|
||||
//check if any not requested cells no longer need to be requested
|
||||
clearOutOfBoundsCells();
|
||||
//check if any cells should be added
|
||||
@ -342,6 +341,7 @@ public class DrawCellManager {
|
||||
* Updates cells that need updating in this manager
|
||||
*/
|
||||
public void update(){
|
||||
calculateDeltas();
|
||||
if(containsUnrequestedCell() && !containsUndrawableCell()){
|
||||
updateUnrequestedCell();
|
||||
} else if(containsUndrawableCell()){
|
||||
|
||||
@ -155,11 +155,13 @@ public class ClientTerrainManager {
|
||||
* Pushes all terrain data in queue to the gpu and registers the resulting models
|
||||
*/
|
||||
public static void generateTerrainChunkGeometry(){
|
||||
Globals.profiler.beginCpuSample("generateTerrainChunkGeometry");
|
||||
for(TerrainChunkGenQueueItem queueItem : terrainChunkGenerationQueue){
|
||||
Model terrainModel = TerrainChunkModelGeneration.generateTerrainModel(queueItem.getData());
|
||||
Globals.assetManager.registerModelToSpecificString(terrainModel, queueItem.getPromisedHash());
|
||||
}
|
||||
terrainChunkGenerationQueue.clear();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -100,8 +100,14 @@ public class CollisionBodyCreation {
|
||||
collisionEngine.setGravityMode(body, gravityMode);
|
||||
}
|
||||
|
||||
public static void addMass(CollisionEngine collisionEngine, DBody body){
|
||||
|
||||
/**
|
||||
* Sets the offset position of the first geometry in a given body
|
||||
* @param collisionEngine The collision engine
|
||||
* @param body The body
|
||||
* @param offsetPosition The position to offset the first geometry by
|
||||
*/
|
||||
public static void setOffsetPosition(CollisionEngine collisionEngine, DBody body, Vector3d offsetPosition){
|
||||
collisionEngine.setOffsetPosition(body, offsetPosition);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.ode4j.math.DMatrix3;
|
||||
import org.ode4j.math.DVector3;
|
||||
import org.ode4j.math.DVector3C;
|
||||
import org.ode4j.math.DVector4;
|
||||
import org.ode4j.ode.DBody;
|
||||
import org.ode4j.ode.DBox;
|
||||
@ -212,17 +213,22 @@ public class CollisionEngine {
|
||||
* @param time The time to increment the physics simulation by
|
||||
*/
|
||||
public void simulatePhysics(float time){
|
||||
Globals.profiler.beginCpuSample("physics");
|
||||
spaceLock.acquireUninterruptibly();
|
||||
Globals.profiler.beginCpuSample("collide");
|
||||
OdeHelper.spaceCollide(space, 0, nearCallback);
|
||||
Globals.profiler.endCpuSample();
|
||||
// space.collide2(space, collisionWorldData, nearCallback);
|
||||
|
||||
//simulate physics
|
||||
Globals.profiler.beginCpuSample("step physics");
|
||||
world.quickStep(ENGINE_STEP_SIZE);
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
// remove all contact joints
|
||||
contactgroup.empty();
|
||||
spaceLock.release();
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -373,6 +379,7 @@ public class CollisionEngine {
|
||||
* Main function to resynchronize entity positions with physics object positions after impulses are applied.
|
||||
*/
|
||||
public void updateDynamicObjectTransforms(){
|
||||
Globals.profiler.beginCpuSample("updateDynamicObjectTransforms");
|
||||
spaceLock.acquireUninterruptibly();
|
||||
for(Collidable collidable : collidableList){
|
||||
if(collidable.getParentTracksCollidable()){
|
||||
@ -387,6 +394,7 @@ public class CollisionEngine {
|
||||
}
|
||||
}
|
||||
spaceLock.release();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
public void registerCollisionObject(DBody body, Collidable collidable){
|
||||
@ -737,7 +745,20 @@ public class CollisionEngine {
|
||||
* @param gravityMode the gravity mode
|
||||
*/
|
||||
protected void setGravityMode(DBody body, boolean gravityMode){
|
||||
spaceLock.acquireUninterruptibly();
|
||||
body.setGravityMode(gravityMode);
|
||||
spaceLock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset position of the first geometry in the body
|
||||
* @param body The body
|
||||
* @param offsetVector The offset position
|
||||
*/
|
||||
protected void setOffsetPosition(DBody body, Vector3d offsetVector){
|
||||
spaceLock.acquireUninterruptibly();
|
||||
body.getGeomIterator().next().setOffsetPosition(offsetVector.x,offsetVector.y,offsetVector.z);
|
||||
spaceLock.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -45,8 +45,11 @@ public class PhysicsEntityUtils {
|
||||
physicsTemplate.getDimension2(),
|
||||
Collidable.TYPE_CREATURE_BIT
|
||||
);
|
||||
DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next();
|
||||
cylinder.setOffsetPosition(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ());
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
Globals.clientSceneWrapper.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
|
||||
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
|
||||
@ -114,8 +117,11 @@ public class PhysicsEntityUtils {
|
||||
physicsTemplate.getDimension2(),
|
||||
Collidable.TYPE_CREATURE_BIT
|
||||
);
|
||||
DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next();
|
||||
cylinder.setOffsetPosition(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ());
|
||||
CollisionBodyCreation.setOffsetPosition(
|
||||
realm.getCollisionEngine(),
|
||||
rigidBody,
|
||||
new Vector3d(physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ())
|
||||
);
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
|
||||
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
|
||||
|
||||
@ -44,6 +44,8 @@ public class CameraHandler {
|
||||
}
|
||||
|
||||
public void updateGlobalCamera(){
|
||||
Globals.profiler.beginCpuSample("updateGlobalCamera");
|
||||
if(Globals.playerCamera != null){
|
||||
cameraSpeed = 2.5f * (float)Globals.timekeeper.getMostRecentRawFrametime();
|
||||
|
||||
if(Crosshair.getCrosshairActive()){
|
||||
@ -106,6 +108,8 @@ public class CameraHandler {
|
||||
|
||||
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
public float getYaw(){
|
||||
return yaw;
|
||||
|
||||
@ -30,6 +30,7 @@ import electrosphere.controls.MouseCallback;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.engine.assetmanager.AssetManager;
|
||||
import electrosphere.engine.loadingthreads.LoadingThread;
|
||||
import electrosphere.engine.profiler.Profiler;
|
||||
import electrosphere.engine.time.Timekeeper;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.Scene;
|
||||
@ -112,6 +113,17 @@ public class Globals {
|
||||
public static boolean ENGINE_DEBUG = true;
|
||||
|
||||
|
||||
//
|
||||
//Profiler
|
||||
//
|
||||
public static Profiler profiler;
|
||||
|
||||
//
|
||||
//Garbage Collection
|
||||
//
|
||||
public static boolean EXPLICIT_GC = true;
|
||||
|
||||
|
||||
//
|
||||
//Client connection to server
|
||||
//
|
||||
@ -440,6 +452,8 @@ public class Globals {
|
||||
}
|
||||
//client synchronization manager
|
||||
clientSynchronizationManager = new ClientSynchronizationManager();
|
||||
//profiler
|
||||
profiler = new Profiler();
|
||||
}
|
||||
|
||||
public static void initDefaultAudioResources(){
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package electrosphere.engine;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.glfwGetTime;
|
||||
import static org.lwjgl.glfw.GLFW.glfwTerminate;
|
||||
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
|
||||
|
||||
@ -11,10 +10,10 @@ import org.ode4j.ode.OdeHelper;
|
||||
|
||||
import electrosphere.audio.AudioEngine;
|
||||
import electrosphere.audio.VirtualAudioSourceManager;
|
||||
import electrosphere.client.sim.ClientFunctions;
|
||||
import electrosphere.controls.ControlHandler;
|
||||
import electrosphere.engine.cli.CLIParser;
|
||||
import electrosphere.engine.loadingthreads.LoadingThread;
|
||||
import electrosphere.engine.time.Timekeeper;
|
||||
import electrosphere.game.config.UserSettings;
|
||||
import electrosphere.game.server.world.MacroData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
@ -214,15 +213,12 @@ public class Main {
|
||||
public static void mainLoop(long maxFrames){
|
||||
|
||||
double functionTrackTimeStart = 0;
|
||||
boolean captureFramerate = false;
|
||||
//main loop
|
||||
while (running) {
|
||||
|
||||
Globals.profiler.beginRootCpuSample("frame");
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin Main Loop Frame");
|
||||
|
||||
//sets whether to capture framerates of current frame
|
||||
captureFramerate = Globals.timekeeper.getNumberOfRenderFramesElapsed() % 10 == 0;
|
||||
|
||||
//
|
||||
//Update timekeeper
|
||||
//
|
||||
@ -230,26 +226,14 @@ public class Main {
|
||||
|
||||
|
||||
|
||||
//
|
||||
// track total frametiime in debug graph
|
||||
//
|
||||
if(captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("totalframerate",Globals.timekeeper.getMostRecentRawFrametime() * 1000);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// A S S E T M A N A G E R S T U F F
|
||||
///
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
functionTrackTimeStart = glfwGetTime();
|
||||
}
|
||||
if(Globals.RUN_CLIENT){
|
||||
Globals.profiler.beginCpuSample("Load Assets");
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin load assets");
|
||||
Globals.assetManager.loadAssetsInQueue();
|
||||
}
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("assetLoad",(glfwGetTime()-functionTrackTimeStart)*1000);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -258,39 +242,26 @@ public class Main {
|
||||
///
|
||||
/// C L I E N T N E T W O R K I N G S T U F F
|
||||
///
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
functionTrackTimeStart = glfwGetTime();
|
||||
}
|
||||
//Why is this its own function? Just to get the networking code out of main()
|
||||
if(Globals.clientConnection != null){
|
||||
Globals.profiler.beginCpuSample("Client networking");
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin parse client messages");
|
||||
Globals.clientConnection.parseMessages();
|
||||
}
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("clientNetwork",(glfwGetTime()-functionTrackTimeStart)*1000);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
//handle framestep
|
||||
if(framestep == 1){
|
||||
framestep = 0;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// I N P U T C O N T R O L S
|
||||
///
|
||||
//Poll controls
|
||||
if(Globals.RUN_CLIENT){
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
functionTrackTimeStart = glfwGetTime();
|
||||
}
|
||||
Globals.profiler.beginCpuSample("Poll Controls");
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin recapture screen");
|
||||
Globals.controlHandler.pollControls();
|
||||
RenderingEngine.recaptureIfNecessary();
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("controls",(glfwGetTime()-functionTrackTimeStart)*1000);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -299,28 +270,26 @@ public class Main {
|
||||
/// M A I N S I M U L A T I O N I N N E R L O O P
|
||||
///
|
||||
|
||||
while(Globals.timekeeper.pullFromAccumulator()){
|
||||
int simFrameHardcapCounter = 0;
|
||||
while(Globals.timekeeper.pullFromAccumulator() && framestep > 0 && simFrameHardcapCounter < Timekeeper.SIM_FRAME_HARDCAP){
|
||||
|
||||
//sim frame hard cap counter increment
|
||||
simFrameHardcapCounter++;
|
||||
//handle framestep
|
||||
if(framestep == 1){
|
||||
framestep = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// C L I E N T S I M U L A T I O N S T U F F
|
||||
///
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin client simulation");
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
functionTrackTimeStart = glfwGetTime();
|
||||
}
|
||||
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
|
||||
ClientFunctions.runBeforeSimulationFunctions();
|
||||
}
|
||||
if(Globals.clientSimulation != null && Globals.clientSimulation.isLoadingTerrain() && framestep > 0){
|
||||
ClientFunctions.loadTerrain();
|
||||
}
|
||||
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
|
||||
if(Globals.clientSimulation != null){
|
||||
Globals.profiler.beginCpuSample("Client simulation");
|
||||
Globals.clientSimulation.simulate();
|
||||
}
|
||||
if(Globals.clientSimulation != null && Globals.clientSimulation.isReady() && framestep > 0){
|
||||
ClientFunctions.runClientFunctions();
|
||||
}
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("clientsim",(glfwGetTime()-functionTrackTimeStart)*1000);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -336,10 +305,8 @@ public class Main {
|
||||
///
|
||||
/// S E R V E R M I C R O S I M U L A T I O N
|
||||
///
|
||||
Globals.profiler.beginCpuSample("Server simulation");
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin server micro simulation");
|
||||
if(!!Globals.HEADLESS && captureFramerate){
|
||||
functionTrackTimeStart = glfwGetTime();
|
||||
}
|
||||
if(Globals.realmManager != null){
|
||||
Globals.realmManager.simulate();
|
||||
}
|
||||
@ -348,12 +315,10 @@ public class Main {
|
||||
/// M A C R O S I M U L A T I O N S T U F F
|
||||
///
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin server macro simulation");
|
||||
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady() && framestep > 0){
|
||||
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady()){
|
||||
Globals.macroSimulation.simulate();
|
||||
}
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("serversim",(glfwGetTime()-functionTrackTimeStart)*1000);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -363,14 +328,10 @@ public class Main {
|
||||
/// M A I N R E N D E R F U N C T I O N
|
||||
///
|
||||
LoggerInterface.loggerEngine.DEBUG("Begin rendering call");
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
functionTrackTimeStart = glfwGetTime();
|
||||
}
|
||||
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
|
||||
Globals.profiler.beginCpuSample("render");
|
||||
Globals.renderingEngine.drawScreen();
|
||||
}
|
||||
if(!Globals.HEADLESS && captureFramerate){
|
||||
ImGuiWindowMacros.addGlobalFramerateDatapoint("render",(glfwGetTime()-functionTrackTimeStart)*1000);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -379,7 +340,11 @@ public class Main {
|
||||
///
|
||||
/// G A R B A G E C H E C K
|
||||
///
|
||||
Globals.profiler.beginCpuSample("gc");
|
||||
if(Globals.EXPLICIT_GC){
|
||||
System.gc();
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
|
||||
|
||||
@ -407,23 +372,28 @@ public class Main {
|
||||
//
|
||||
// C L E A N U P T I M E V A R I A B L E S
|
||||
//
|
||||
Globals.profiler.beginCpuSample("sleep");
|
||||
if(Globals.timekeeper.getMostRecentRawFrametime() < targetFramePeriod){
|
||||
sleep((int)(1000.0 * (targetFramePeriod - Globals.timekeeper.getMostRecentRawFrametime())));
|
||||
} else {
|
||||
sleep(1);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
Globals.timekeeper.numberOfRenderedFrames++;
|
||||
|
||||
if(maxFrames > 0 && Globals.timekeeper.numberOfRenderedFrames > maxFrames){
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End main loop
|
||||
//
|
||||
LoggerInterface.loggerEngine.DEBUG("End Main Loop Frame");
|
||||
Globals.profiler.endCpuSample();
|
||||
|
||||
}
|
||||
|
||||
LoggerInterface.loggerEngine.ERROR("ENGINE SHUTDOWN", new Exception());
|
||||
|
||||
LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN");
|
||||
//
|
||||
// S H U T D O W N
|
||||
//
|
||||
|
||||
@ -5,6 +5,7 @@ import electrosphere.collision.CollisionBodyCreation;
|
||||
import electrosphere.collision.CollisionEngine;
|
||||
import electrosphere.collision.PhysicsUtils;
|
||||
import electrosphere.collision.collidable.Collidable;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.actor.ActorShaderMask;
|
||||
import electrosphere.renderer.buffer.HomogenousInstancedArray;
|
||||
import electrosphere.renderer.buffer.HomogenousUniformBuffer;
|
||||
@ -303,6 +304,8 @@ public class AssetManager {
|
||||
AudioBuffer rVal = null;
|
||||
if(audioLoadedIntoMemory.containsKey(path)){
|
||||
rVal = audioLoadedIntoMemory.get(path);
|
||||
} else {
|
||||
LoggerInterface.loggerAudio.WARNING("Failed to find audio " + path);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
72
src/main/java/electrosphere/engine/profiler/Profiler.java
Normal file
72
src/main/java/electrosphere/engine/profiler/Profiler.java
Normal file
@ -0,0 +1,72 @@
|
||||
package electrosphere.engine.profiler;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.lwjgl.util.remotery.Remotery;
|
||||
|
||||
/**
|
||||
* A profiler for monitoring engine performance
|
||||
*/
|
||||
public class Profiler {
|
||||
|
||||
//controls whether to profile or not
|
||||
public static final boolean PROFILE = true;
|
||||
|
||||
//pointer to the global instance
|
||||
long pointer = -1;
|
||||
|
||||
/**
|
||||
* Creates the profiler
|
||||
*/
|
||||
public Profiler(){
|
||||
try(MemoryStack stack = MemoryStack.stackPush()){
|
||||
PointerBuffer allocBuffer = stack.mallocPointer(1);
|
||||
Remotery.rmt_CreateGlobalInstance(allocBuffer);
|
||||
pointer = allocBuffer.get();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a CPU sample
|
||||
* @param sampleName The name of the sample
|
||||
*/
|
||||
public void beginCpuSample(String sampleName){
|
||||
if(PROFILE){
|
||||
Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_None, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins an aggregate CPU sample (must create a regular cpu sample of same type outside function this is inside of to encapsule all calls to aggregate)
|
||||
* @param sampleName The name of the sample
|
||||
*/
|
||||
public void beginAggregateCpuSample(String sampleName){
|
||||
if(PROFILE){
|
||||
Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_Aggregate, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a Root CPU sample (will assert if another sample is not ended before this one)
|
||||
* @param sampleName The name of the root sample
|
||||
*/
|
||||
public void beginRootCpuSample(String sampleName){
|
||||
if(PROFILE){
|
||||
Remotery.rmt_BeginCPUSample(sampleName, Remotery.RMTSF_Root, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a CPU sample
|
||||
* @param sampleName The name of the sample
|
||||
*/
|
||||
public void endCpuSample(){
|
||||
if(PROFILE){
|
||||
Remotery.rmt_EndCPUSample();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -30,6 +30,12 @@ public class Timekeeper {
|
||||
//the raw (not simulation) frametime of the most recent frame
|
||||
double mostRecentRawFrametime = 0;
|
||||
|
||||
//The maximum amount of time that can overflow (ie cause more than one sim frame/render frame) before the sim frames are tossed out
|
||||
static double overflowMax = 20;
|
||||
|
||||
//the maximum number of simulation frames that can happen in a row before the main loop immediately skips more
|
||||
public static final int SIM_FRAME_HARDCAP = 3;
|
||||
|
||||
|
||||
|
||||
|
||||
@ -65,8 +71,8 @@ public class Timekeeper {
|
||||
double newTime = getTime();
|
||||
double frameTime = newTime - currentTime;
|
||||
mostRecentRawFrametime = frameTime;
|
||||
if(frameTime > 0.25){
|
||||
frameTime = 0.25;
|
||||
if(frameTime > overflowMax){
|
||||
frameTime = overflowMax;
|
||||
}
|
||||
currentTime = newTime;
|
||||
//add to accumulator
|
||||
|
||||
@ -146,9 +146,11 @@ public class Scene {
|
||||
* Simulates all behavior trees stored in the entity manager
|
||||
*/
|
||||
public void simulateBehaviorTrees(float deltaTime){
|
||||
Globals.profiler.beginCpuSample("Scene.simulateBehaviorTrees");
|
||||
for(BehaviorTree tree : behaviorTreeList){
|
||||
tree.simulate(deltaTime);
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -76,6 +76,17 @@ public class AttachUtils {
|
||||
* Client version of attachment update functions
|
||||
*/
|
||||
public static void clientUpdateAttachedEntityPositions(){
|
||||
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateAttachedEntityPositions");
|
||||
updateBoneAttachments();
|
||||
updateNonBoneAttachments();
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates entities attached to bones
|
||||
*/
|
||||
private static void updateBoneAttachments(){
|
||||
Globals.profiler.beginCpuSample("AttachUtils.updateBoneAttachments");
|
||||
//update entities attached to bones of other entities
|
||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
||||
Entity parent;
|
||||
@ -111,13 +122,21 @@ public class AttachUtils {
|
||||
EntityUtils.getPosition(currentEntity).set(new Vector3d(parentPosition).add(positionOffset));
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
private static void updateNonBoneAttachments(){
|
||||
Globals.profiler.beginCpuSample("AttachUtils.updateNonBoneAttachments");
|
||||
Matrix4d parentTransform = new Matrix4d().identity();
|
||||
Vector3d position = new Vector3d();
|
||||
Quaterniond rotation = new Quaterniond();
|
||||
Vector3d scaleRaw = new Vector3d();
|
||||
Vector3f scale = new Vector3f();
|
||||
Entity parent;
|
||||
Matrix4f transform;
|
||||
//update entities attached to centerpoint + transform of other entities
|
||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.TRANSFORM_ATTACHED)){
|
||||
Entity parent;
|
||||
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
||||
Matrix4f transform;
|
||||
if((transform = getTransformOffset(currentEntity))!=null){
|
||||
//parent objects
|
||||
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||
@ -130,11 +149,10 @@ public class AttachUtils {
|
||||
.scale(parentScale.x,parentScale.y,parentScale.z)
|
||||
.mul(transform);
|
||||
//transform bone space
|
||||
Vector4d positionRaw = parentTransform.transform(new Vector4d(0,0,0,1));
|
||||
Vector3d position = new Vector3d(positionRaw.x,positionRaw.y,positionRaw.z);
|
||||
Quaterniond rotation = parentTransform.getUnnormalizedRotation(new Quaterniond()).normalize();
|
||||
Vector3d scaleRaw = parentTransform.getScale(new Vector3d());
|
||||
Vector3f scale = new Vector3f((float)scaleRaw.x,(float)scaleRaw.y,(float)scaleRaw.z);
|
||||
parentTransform.getTranslation(position);
|
||||
parentTransform.getUnnormalizedRotation(rotation).normalize();
|
||||
parentTransform.getScale(scaleRaw);
|
||||
scale.set((float)scaleRaw.x,(float)scaleRaw.y,(float)scaleRaw.z);
|
||||
//transform worldspace
|
||||
// position.add(new Vector3d(EntityUtils.getPosition(parent)));
|
||||
//set
|
||||
@ -144,6 +162,7 @@ public class AttachUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
|
||||
@ -217,7 +236,7 @@ public class AttachUtils {
|
||||
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||
Vector3d childPosition = EntityUtils.getPosition(toAttach);
|
||||
Vector3d offset = new Vector3d(childPosition).sub(parentPosition);
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
|
||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.TRANSFORM_ATTACHED);
|
||||
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
|
||||
toAttach.putData(EntityDataStrings.ATTACH_PARENT, parent);
|
||||
toAttach.putData(EntityDataStrings.ATTACH_TARGET_BASE, true);
|
||||
|
||||
@ -126,8 +126,7 @@ public class ProceduralTree {
|
||||
treeModel.getPhysicsBody().getDimension2(),
|
||||
Collidable.TYPE_STATIC_BIT
|
||||
);
|
||||
DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next();
|
||||
cylinder.setOffsetPosition(0,treeModel.getPhysicsBody().getOffsetY(),0);
|
||||
CollisionBodyCreation.setOffsetPosition(Globals.clientSceneWrapper.getCollisionEngine(), rigidBody, new Vector3d(0,treeModel.getPhysicsBody().getOffsetY(),0));
|
||||
CollisionBodyCreation.setKinematic(Globals.clientSceneWrapper.getCollisionEngine(), rigidBody);
|
||||
Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_OBJECT);
|
||||
trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
|
||||
@ -393,8 +392,7 @@ public class ProceduralTree {
|
||||
treeModel.getPhysicsBody().getDimension2(),
|
||||
Collidable.TYPE_STATIC_BIT
|
||||
);
|
||||
DCylinder cylinder = (DCylinder)rigidBody.getGeomIterator().next();
|
||||
cylinder.setOffsetPosition(0,treeModel.getPhysicsBody().getOffsetY(),0);
|
||||
CollisionBodyCreation.setOffsetPosition(realm.getCollisionEngine(), rigidBody, new Vector3d(0,treeModel.getPhysicsBody().getOffsetY(),0));
|
||||
CollisionBodyCreation.setKinematic(realm.getCollisionEngine(), rigidBody);
|
||||
Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_FOLIAGE_STATIC);
|
||||
trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
|
||||
|
||||
@ -176,6 +176,8 @@ public class ClientNetworking implements Runnable{
|
||||
}
|
||||
|
||||
|
||||
static final int MAX_MESSAGES_PARSED = 1000;
|
||||
|
||||
public void parseMessages(){
|
||||
if(initialized){
|
||||
while(parser.hasIncomingMessaage()){
|
||||
@ -187,7 +189,9 @@ public class ClientNetworking implements Runnable{
|
||||
//print network message
|
||||
printMessage(message);
|
||||
//do something
|
||||
Globals.profiler.beginCpuSample("ClientProtocol.handleMessage");
|
||||
clientProtocol.handleMessage(message);
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ public class ClientProtocol {
|
||||
boolean hasReceivedWorld = false;
|
||||
|
||||
public void handleMessage(NetworkMessage message){
|
||||
Globals.profiler.beginAggregateCpuSample("ClientProtocol.handleMessage");
|
||||
switch(message.getType()){
|
||||
case ENTITY_MESSAGE:
|
||||
EntityProtocol.handleEntityMessage((EntityMessage)message);
|
||||
@ -58,6 +59,7 @@ public class ClientProtocol {
|
||||
SynchronizationProtocol.handleSynchronizationMessage((SynchronizationMessage)message);
|
||||
break;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
// void handleStatusMessage(StatusMessage message){
|
||||
|
||||
@ -21,6 +21,7 @@ import electrosphere.util.Utilities;
|
||||
public class EntityProtocol {
|
||||
|
||||
protected static void handleEntityMessage(EntityMessage message){
|
||||
Globals.profiler.beginCpuSample("EntityProtocol.handleEntityMessage");
|
||||
LoggerInterface.loggerNetworking.DEBUG("Parse entity message of type " + message.getMessageSubtype());
|
||||
Entity newlySpawnedEntity;
|
||||
switch(message.getMessageSubtype()){
|
||||
@ -122,6 +123,7 @@ public class EntityProtocol {
|
||||
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
|
||||
} break;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import electrosphere.net.server.player.Player;
|
||||
public class PlayerProtocol {
|
||||
|
||||
protected static void handlePlayerMessage(PlayerMessage message){
|
||||
Globals.profiler.beginCpuSample("PlayerProtocol.handlePlayerMessage");
|
||||
switch(message.getMessageSubtype()){
|
||||
case SET_ID:
|
||||
Globals.clientPlayer = new Player(message.getplayerID());
|
||||
@ -20,6 +21,7 @@ public class PlayerProtocol {
|
||||
Globals.clientPlayerData.setWorldPos(new Vector3i(message.getinitialDiscretePositionX(), message.getinitialDiscretePositionY(), message.getinitialDiscretePositionZ()));
|
||||
break;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
public class SynchronizationProtocol {
|
||||
|
||||
protected static void handleSynchronizationMessage(SynchronizationMessage message){
|
||||
Globals.profiler.beginCpuSample("SynchronizationProtocol.handleSynchronizationMessage");
|
||||
switch(message.getMessageSubtype()){
|
||||
case UPDATECLIENTSTATE:
|
||||
case ATTACHTREE:
|
||||
@ -13,6 +14,7 @@ public class SynchronizationProtocol {
|
||||
Globals.clientSynchronizationManager.pushMessage(message);
|
||||
break;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
public class TerrainProtocol {
|
||||
|
||||
protected static void handleTerrainMessage(TerrainMessage message){
|
||||
Globals.profiler.beginCpuSample("TerrainProtocol.handleTerrainMessage");
|
||||
switch(message.getMessageSubtype()){
|
||||
case RESPONSEMETADATA:
|
||||
Globals.clientWorldData = new ClientWorldData(
|
||||
@ -60,6 +61,7 @@ public class TerrainProtocol {
|
||||
LoggerInterface.loggerNetworking.WARNING("Client networking: Unhandled message of type: " + message.getMessageSubtype());
|
||||
break;
|
||||
}
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package electrosphere.renderer.pipelines;
|
||||
|
||||
import org.lwjgl.opengl.GL40;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
@ -10,6 +11,7 @@ public class CompositePipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("CompositePipeline.render");
|
||||
//
|
||||
//Setup to render screen textures & bind screen framebuffer
|
||||
//
|
||||
@ -63,7 +65,7 @@ public class CompositePipeline implements RenderPipeline {
|
||||
GL40.glBindVertexArray(0);
|
||||
|
||||
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("DebugContentPipeline.render");
|
||||
|
||||
//bind screen fbo
|
||||
RenderingEngine.screenFramebuffer.bind();
|
||||
openGLState.glDepthTest(true);
|
||||
@ -202,6 +204,8 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -22,6 +22,8 @@ public class MainContentNoOITPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("MainContentNoOITPipeline.render");
|
||||
|
||||
//bind screen fbo
|
||||
RenderingEngine.screenFramebuffer.bind();
|
||||
openGLState.glDepthTest(true);
|
||||
@ -75,6 +77,8 @@ public class MainContentNoOITPipeline implements RenderPipeline {
|
||||
currentActor.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
}
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ public class MainContentPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("MainContentPipeline.render");
|
||||
|
||||
Matrix4d modelTransformMatrix = new Matrix4d();
|
||||
|
||||
@ -214,6 +215,8 @@ public class MainContentPipeline implements RenderPipeline {
|
||||
|
||||
|
||||
// glBindVertexArray(0);
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ public class NormalsForOutlinePipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("NormalsForOutlinePipeline.render");
|
||||
/*
|
||||
gameImageNormalsTexture;
|
||||
static Framebuffer gameImageNormalsFramebuffer;
|
||||
@ -83,6 +84,8 @@ public class NormalsForOutlinePipeline implements RenderPipeline {
|
||||
currentActor.draw(renderPipelineState,openGLState);
|
||||
}
|
||||
}
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@ public class PostProcessingPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("PostProcessingPipeline.render");
|
||||
//
|
||||
// Outline normals
|
||||
//
|
||||
@ -40,6 +41,8 @@ public class PostProcessingPipeline implements RenderPipeline {
|
||||
GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6);
|
||||
GL40.glBindVertexArray(0);
|
||||
}
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ public class RenderScreenPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("RenderScreenPipeline.render");
|
||||
//
|
||||
//unbind texture channels
|
||||
//
|
||||
@ -71,6 +72,8 @@ public class RenderScreenPipeline implements RenderPipeline {
|
||||
}
|
||||
GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6);
|
||||
GL40.glBindVertexArray(0);
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ public class ShadowMapPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("ShadowMapPipeline.render");
|
||||
Matrix4d modelTransformMatrix = new Matrix4d();
|
||||
|
||||
//set the viewport to shadow map size
|
||||
@ -105,6 +106,8 @@ public class ShadowMapPipeline implements RenderPipeline {
|
||||
openGLState.glViewport(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||||
//resume culling backface
|
||||
// glCullFace(GL_BACK);
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ public class UIPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("UIPipeline.render");
|
||||
|
||||
//
|
||||
//Black background
|
||||
@ -73,6 +74,7 @@ public class UIPipeline implements RenderPipeline {
|
||||
}
|
||||
}
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ public class VolumeBufferPipeline implements RenderPipeline {
|
||||
|
||||
@Override
|
||||
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
|
||||
Globals.profiler.beginCpuSample("VolumeBufferPipeline.render");
|
||||
Matrix4d modelTransformMatrix = new Matrix4d();
|
||||
|
||||
//set the viewport to shadow map size
|
||||
@ -189,6 +190,8 @@ public class VolumeBufferPipeline implements RenderPipeline {
|
||||
openGLState.glBindFramebuffer(GL40.GL_FRAMEBUFFER,0);
|
||||
//resume culling backface
|
||||
GL40.glDisable(GL40.GL_CULL_FACE);
|
||||
|
||||
Globals.profiler.endCpuSample();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ public class EnvironmentGenerator {
|
||||
|
||||
public static void generateForest(Realm realm, ServerDataCell cell, Vector3i worldPos, long randomizer){
|
||||
Random rand = new Random(randomizer);
|
||||
int targetNum = (int)(rand.nextFloat() * 5) + 5;
|
||||
int targetNum = (int)(rand.nextFloat() * 3) + 3;
|
||||
LoggerInterface.loggerGameLogic.DEBUG("generate forest");
|
||||
for(int i = 0; i < targetNum; i++){
|
||||
Vector3d position = new Vector3d(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user