From 45add5e0d422ff380e5b02d5e7ae77c6bbf62c43 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Thu, 9 May 2024 23:21:46 +0530 Subject: [PATCH] add profiler modes and improve alloc in raycasts --- src/Console.hx | 8 ++++++++ src/Main.hx | 10 ++++++---- src/MarbleGame.hx | 2 +- src/MarbleWorld.hx | 22 +++++++++++----------- src/ProfilerUI.hx | 25 +++++++++++++++++++------ src/Renderer.hx | 14 +++++++------- src/collision/BVHTree.hx | 4 ++-- src/collision/BoxCollisionEntity.hx | 3 +-- src/collision/CollisionEntity.hx | 5 ++--- src/collision/CollisionSurface.hx | 4 +--- src/collision/CollisionWorld.hx | 13 ++++++++++--- src/collision/Grid.hx | 2 +- src/collision/SphereCollisionEntity.hx | 3 +-- src/modes/HuntMode.hx | 2 +- src/octree/IOctreeObject.hx | 2 +- src/octree/OctreeNode.hx | 3 ++- 16 files changed, 74 insertions(+), 48 deletions(-) diff --git a/src/Console.hx b/src/Console.hx index 0dad0f96..052e1574 100644 --- a/src/Console.hx +++ b/src/Console.hx @@ -201,6 +201,14 @@ class Console { #if sys hl.Api.checkReload(); #end + } else if (cmdType == "profile") { + if (cmdSplit.length == 2) { + var scale = Std.parseInt(cmdSplit[1]); + ProfilerUI.setDisplayMode(scale); + log("FPS Display set to " + scale); + } else { + error("Expected one argument, got " + (cmdSplit.length - 1)); + } } else { error("Unknown command"); } diff --git a/src/Main.hx b/src/Main.hx index 6ca98cfc..3ae89905 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -141,8 +141,8 @@ class Main extends hxd.App { override function update(dt:Float) { super.update(dt); - ProfilerUI.begin(); - ProfilerUI.measure("updateBegin"); + ProfilerUI.begin(1); + ProfilerUI.measure("updateBegin", 1); if (loaded) { // try { // timeAccumulator += dt; @@ -160,16 +160,18 @@ class Main extends hxd.App { // world.update(dt); ProfilerUI.update(this.engine.fps); } + ProfilerUI.end(1); } override function render(e:h3d.Engine) { // this.world.render(e); + ProfilerUI.begin(0); if (loaded) { - ProfilerUI.measure("renderBegin"); + ProfilerUI.measure("renderBegin", 0); marbleGame.render(e); } super.render(e); - ProfilerUI.end(); + ProfilerUI.end(0); } static function main() { diff --git a/src/MarbleGame.hx b/src/MarbleGame.hx index e740214e..3be0f9a0 100644 --- a/src/MarbleGame.hx +++ b/src/MarbleGame.hx @@ -247,7 +247,7 @@ class MarbleGame { wheel: _mouseWheelDelta, handled: false } - ProfilerUI.measure("canvasUpdate"); + ProfilerUI.measure("canvasUpdate", 1); canvas.update(dt, mouseState); } } diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index d560fefb..50c92ff1 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -1424,7 +1424,7 @@ class MarbleWorld extends Scheduler { } public function advanceWorld(dt:Float) { - ProfilerUI.measure("updateTimer"); + ProfilerUI.measure("updateTimer", 1); this.updateTimer(dt); this.tickSchedule(timeState.currentAttemptTime); @@ -1438,7 +1438,7 @@ class MarbleWorld extends Scheduler { this.updateGameState(); this.updateBlast(this.marble, timeState); - ProfilerUI.measure("updateDTS"); + ProfilerUI.measure("updateDTS", 1); for (obj in dtsObjects) { obj.update(timeState); } @@ -1446,7 +1446,7 @@ class MarbleWorld extends Scheduler { obj.update(timeState); } - ProfilerUI.measure("updateMarbles"); + ProfilerUI.measure("updateMarbles", 1); marble.update(timeState, collisionWorld, this.pathedInteriors); for (client => marble in clientMarbles) { marble.update(timeState, collisionWorld, this.pathedInteriors); @@ -1544,7 +1544,7 @@ class MarbleWorld extends Scheduler { this.isReplayingMovement = false; } - ProfilerUI.measure("updateTimer"); + ProfilerUI.measure("updateTimer", 1); this.updateTimer(dt); // if ((Key.isPressed(Settings.controlsSettings.respawn) || Gamepad.isPressed(Settings.gamepadSettings.respawn)) @@ -1586,7 +1586,7 @@ class MarbleWorld extends Scheduler { this.updateGameState(); if (!this.isMultiplayer) this.updateBlast(this.marble, timeState); - ProfilerUI.measure("updateDTS"); + ProfilerUI.measure("updateDTS", 1); for (obj in dtsObjects) { obj.update(timeState); } @@ -1598,7 +1598,7 @@ class MarbleWorld extends Scheduler { // inputRecorder.recordInput(timeState.currentAttemptTime); // } - ProfilerUI.measure("updateMarbles"); + ProfilerUI.measure("updateMarbles", 1); if (this.isMultiplayer) { tickAccumulator += timeState.dt; while (tickAccumulator >= 0.032) { @@ -1669,14 +1669,14 @@ class MarbleWorld extends Scheduler { // Update camera separately marble.camera.update(timeState.currentAttemptTime, realDt); } - ProfilerUI.measure("updateParticles"); + ProfilerUI.measure("updateParticles", 1); if (this.rewinding) { this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt * rewindManager.timeScale); } else this.particleManager.update(1000 * timeState.timeSinceLoad, dt); - ProfilerUI.measure("updatePlayGui"); + ProfilerUI.measure("updatePlayGui", 1); this.playGui.update(timeState); - ProfilerUI.measure("updateAudio"); + ProfilerUI.measure("updateAudio", 1); AudioManager.update(this.scene); if (!this.isMultiplayer) { @@ -1713,10 +1713,10 @@ class MarbleWorld extends Scheduler { if (_instancesNeedsUpdate) { if (this.radar != null) this.radar.render(); - ProfilerUI.measure("updateInstances"); + ProfilerUI.measure("updateInstances", 0); this.instanceManager.render(); if (this.marble != null && this.marble.cubemapRenderer != null) { - ProfilerUI.measure("renderCubemap"); + ProfilerUI.measure("renderCubemap", 0); this.marble.cubemapRenderer.position.load(this.marble.getAbsPos().getPosition()); this.marble.cubemapRenderer.render(e); diff --git a/src/ProfilerUI.hx b/src/ProfilerUI.hx index d1fe2243..901b9beb 100644 --- a/src/ProfilerUI.hx +++ b/src/ProfilerUI.hx @@ -17,6 +17,7 @@ class ProfilerUI { public static var instance:ProfilerUI; static var enabled:Bool = false; + static var mode:Int = 0; public function new(s2d:h2d.Scene) { if (instance != null) @@ -26,22 +27,25 @@ class ProfilerUI { this.s2d = s2d; } - public static function begin() { + public static function begin(type:Int) { if (!enabled) return; - instance.debugProfiler.begin(); + if (type == mode) + instance.debugProfiler.begin(); } - public static function measure(name:String) { + public static function measure(name:String, type:Int) { if (!enabled) return; - instance.debugProfiler.measure(name); + if (type == mode) + instance.debugProfiler.measure(name); } - public static function end() { + public static function end(type:Int) { if (!enabled) return; - instance.debugProfiler.end(); + if (type == mode) + instance.debugProfiler.end(); } public static function update(fps:Float) { @@ -77,6 +81,8 @@ class ProfilerUI { instance.networkStats = new Text(DefaultFont.get(), instance.s2d); instance.networkStats.y = 150; instance.networkStats.color = new Vector(1, 1, 1, 1); + + instance.debugProfiler.end(); // End current frame } else { instance.debugProfiler.remove(); instance.fpsCounter.remove(); @@ -87,6 +93,13 @@ class ProfilerUI { } } + public static function setDisplayMode(m:Int) { + mode = m; + if (instance.debugProfiler != null) { + instance.debugProfiler.end(); // End + } + } + static function updateNetworkStats() { if (MarbleGame.instance.world != null && MarbleGame.instance.world.isMultiplayer) { static var lastSentMove = 0; diff --git a/src/Renderer.hx b/src/Renderer.hx index 913463e3..5a7aa56e 100644 --- a/src/Renderer.hx +++ b/src/Renderer.hx @@ -125,26 +125,26 @@ class Renderer extends h3d.scene.Renderer { // ctx.engine.clear(0, 1); if (!cubemapPass) - ProfilerUI.measure("sky"); + ProfilerUI.measure("sky", 0); if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 1) { renderPass(defaultPass, get("sky")); renderPass(defaultPass, get("skyshape"), backToFront); } if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 2) { if (!cubemapPass) - ProfilerUI.measure("interiorZPass"); + ProfilerUI.measure("interiorZPass", 0); renderPass(defaultPass, get("zPass")); if (!cubemapPass) - ProfilerUI.measure("interior"); + ProfilerUI.measure("interior", 0); renderPass(defaultPass, get("interior")); } if (!cubemapPass) - ProfilerUI.measure("render"); + ProfilerUI.measure("render", 0); if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 3) { renderPass(defaultPass, get("default")); } if (!cubemapPass) - ProfilerUI.measure("glow"); + ProfilerUI.measure("glow", 0); if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) renderPass(defaultPass, get("glowPre")); @@ -177,7 +177,7 @@ class Renderer extends h3d.scene.Renderer { } } if (!cubemapPass) - ProfilerUI.measure("refract"); + ProfilerUI.measure("refract", 0); // Refraction pass if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { var refractObjects = get("refract"); @@ -189,7 +189,7 @@ class Renderer extends h3d.scene.Renderer { } } if (!cubemapPass) - ProfilerUI.measure("alpha"); + ProfilerUI.measure("alpha", 0); if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { renderPass(defaultPass, get("alpha"), backToFront); diff --git a/src/collision/BVHTree.hx b/src/collision/BVHTree.hx index 2e7b09e4..08d5c8f2 100644 --- a/src/collision/BVHTree.hx +++ b/src/collision/BVHTree.hx @@ -6,7 +6,7 @@ import h3d.col.Bounds; interface IBVHObject { var boundingBox:Bounds; var key:Int; - function rayCast(rayOrigin:Vector, rayDirection:Vector):Array; + function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array):Void; } @:publicFields @@ -475,7 +475,7 @@ class BVHTree { var currentnode = this.nodes[current]; if (currentnode.collideRay(ray)) { if (currentnode.isLeaf) { - res = res.concat(currentnode.object.rayCast(origin, direction)); + currentnode.object.rayCast(origin, direction, res); } else { if (currentnode.child1 != -1) q.push(currentnode.child1); diff --git a/src/collision/BoxCollisionEntity.hx b/src/collision/BoxCollisionEntity.hx index f529d7e9..9332e26e 100644 --- a/src/collision/BoxCollisionEntity.hx +++ b/src/collision/BoxCollisionEntity.hx @@ -48,9 +48,8 @@ class BoxCollisionEntity extends CollisionEntity implements IBVHObject { } } - public override function rayCast(rayOrigin:Vector, rayDirection:Vector) { + public override function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array) { // TEMP cause bruh - return []; } public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { diff --git a/src/collision/CollisionEntity.hx b/src/collision/CollisionEntity.hx index 61959b28..41349ea8 100644 --- a/src/collision/CollisionEntity.hx +++ b/src/collision/CollisionEntity.hx @@ -141,7 +141,7 @@ class CollisionEntity implements IOctreeObject implements IBVHObject { } } - public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array { + public function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array) { var invMatrix = invTransform; var invTPos = invMatrix.clone(); invTPos.transpose(); @@ -164,9 +164,8 @@ class CollisionEntity implements IOctreeObject implements IBVHObject { i.point.transform(transform); i.normal.transform3x3(invTPos); i.normal.normalize(); + results.push(i); } - - return intersections; // } } diff --git a/src/collision/CollisionSurface.hx b/src/collision/CollisionSurface.hx index 5a0557cc..e7c23f65 100644 --- a/src/collision/CollisionSurface.hx +++ b/src/collision/CollisionSurface.hx @@ -139,8 +139,7 @@ class CollisionSurface implements IOctreeObject implements IBVHObject { normals.push(z); } - public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array { - var intersections:Array = []; + public function rayCast(rayOrigin:Vector, rayDirection:Vector, intersections:Array) { var i = 0; while (i < indices.length) { var p1 = getPoint(indices[i]); @@ -157,7 +156,6 @@ class CollisionSurface implements IOctreeObject implements IBVHObject { } i += 3; } - return intersections; } public function support(direction:Vector, transform:Matrix) { diff --git a/src/collision/CollisionWorld.hx b/src/collision/CollisionWorld.hx index d47afc99..e0bf4084 100644 --- a/src/collision/CollisionWorld.hx +++ b/src/collision/CollisionWorld.hx @@ -134,12 +134,19 @@ class CollisionWorld { + rayDirection.x * rayLength, rayStart.y + rayDirection.y * rayLength, rayStart.z + rayDirection.z * rayLength); - var objs = this.octree.boundingSearch(bounds).concat(dynamicOctree.boundingSearch(bounds)).map(x -> cast(x, CollisionEntity)); + var objs = this.octree.boundingSearch(bounds); + var dynObjs = dynamicOctree.boundingSearch(bounds); var results = []; for (obj in objs) { - results = results.concat(obj.rayCast(rayStart, rayDirection)); + var oo = cast(obj, CollisionEntity); + oo.rayCast(rayStart, rayDirection, results); } - results = results.concat(this.staticWorld.rayCast(rayStart, rayDirection)); + + for (obj in dynObjs) { + var oo = cast(obj, CollisionEntity); + oo.rayCast(rayStart, rayDirection, results); + } + // results = results.concat(this.staticWorld.rayCast(rayStart, rayDirection)); return results; } diff --git a/src/collision/Grid.hx b/src/collision/Grid.hx index 800e2b82..88c3e298 100644 --- a/src/collision/Grid.hx +++ b/src/collision/Grid.hx @@ -175,7 +175,7 @@ class Grid { if (surf.key == searchKey) continue; surf.key = searchKey; - results = results.concat(surf.rayCast(origin, direction)); + surf.rayCast(origin, direction, results); } if (tmax.x < tmax.y) { X = X + stepX; diff --git a/src/collision/SphereCollisionEntity.hx b/src/collision/SphereCollisionEntity.hx index 71d00c30..5173d65b 100644 --- a/src/collision/SphereCollisionEntity.hx +++ b/src/collision/SphereCollisionEntity.hx @@ -69,9 +69,8 @@ class SphereCollisionEntity extends CollisionEntity { } } - public override function rayCast(rayOrigin:Vector, rayDirection:Vector) { + public override function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array) { // TEMP cause bruh - return []; } public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { diff --git a/src/modes/HuntMode.hx b/src/modes/HuntMode.hx index 9bf91be9..62bb3d34 100644 --- a/src/modes/HuntMode.hx +++ b/src/modes/HuntMode.hx @@ -84,7 +84,7 @@ class GemOctreeElem implements IOctreeObject { this.priority = priority; } - public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array { + public function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array) { throw new haxe.exceptions.NotImplementedException(); // Not applicable } } diff --git a/src/octree/IOctreeObject.hx b/src/octree/IOctreeObject.hx index ec7d1885..4343b5c3 100644 --- a/src/octree/IOctreeObject.hx +++ b/src/octree/IOctreeObject.hx @@ -13,5 +13,5 @@ class RayIntersectionData { interface IOctreeObject extends IOctreeElement { var boundingBox:Bounds; - function rayCast(rayOrigin:Vector, rayDirection:Vector):Array; + function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array):Void; } diff --git a/src/octree/OctreeNode.hx b/src/octree/OctreeNode.hx index 4e1a8a49..38f0f7fc 100644 --- a/src/octree/OctreeNode.hx +++ b/src/octree/OctreeNode.hx @@ -200,7 +200,8 @@ class OctreeNode implements IOctreeElement { return; for (obj in this.objects) { - var iSecs = obj.rayCast(rayOrigin, rayDirection); + var iSecs = []; + obj.rayCast(rayOrigin, rayDirection, iSecs); for (intersection in iSecs) { var intersectionData = new OctreeIntersection(); intersectionData.distance = rayOrigin.distance(intersection.point);