add profiler modes and improve alloc in raycasts

This commit is contained in:
RandomityGuy 2024-05-09 23:21:46 +05:30
parent a0ee2f1398
commit 45add5e0d4
16 changed files with 74 additions and 48 deletions

View file

@ -201,6 +201,14 @@ class Console {
#if sys #if sys
hl.Api.checkReload(); hl.Api.checkReload();
#end #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 { } else {
error("Unknown command"); error("Unknown command");
} }

View file

@ -141,8 +141,8 @@ class Main extends hxd.App {
override function update(dt:Float) { override function update(dt:Float) {
super.update(dt); super.update(dt);
ProfilerUI.begin(); ProfilerUI.begin(1);
ProfilerUI.measure("updateBegin"); ProfilerUI.measure("updateBegin", 1);
if (loaded) { if (loaded) {
// try { // try {
// timeAccumulator += dt; // timeAccumulator += dt;
@ -160,16 +160,18 @@ class Main extends hxd.App {
// world.update(dt); // world.update(dt);
ProfilerUI.update(this.engine.fps); ProfilerUI.update(this.engine.fps);
} }
ProfilerUI.end(1);
} }
override function render(e:h3d.Engine) { override function render(e:h3d.Engine) {
// this.world.render(e); // this.world.render(e);
ProfilerUI.begin(0);
if (loaded) { if (loaded) {
ProfilerUI.measure("renderBegin"); ProfilerUI.measure("renderBegin", 0);
marbleGame.render(e); marbleGame.render(e);
} }
super.render(e); super.render(e);
ProfilerUI.end(); ProfilerUI.end(0);
} }
static function main() { static function main() {

View file

@ -247,7 +247,7 @@ class MarbleGame {
wheel: _mouseWheelDelta, wheel: _mouseWheelDelta,
handled: false handled: false
} }
ProfilerUI.measure("canvasUpdate"); ProfilerUI.measure("canvasUpdate", 1);
canvas.update(dt, mouseState); canvas.update(dt, mouseState);
} }
} }

View file

@ -1424,7 +1424,7 @@ class MarbleWorld extends Scheduler {
} }
public function advanceWorld(dt:Float) { public function advanceWorld(dt:Float) {
ProfilerUI.measure("updateTimer"); ProfilerUI.measure("updateTimer", 1);
this.updateTimer(dt); this.updateTimer(dt);
this.tickSchedule(timeState.currentAttemptTime); this.tickSchedule(timeState.currentAttemptTime);
@ -1438,7 +1438,7 @@ class MarbleWorld extends Scheduler {
this.updateGameState(); this.updateGameState();
this.updateBlast(this.marble, timeState); this.updateBlast(this.marble, timeState);
ProfilerUI.measure("updateDTS"); ProfilerUI.measure("updateDTS", 1);
for (obj in dtsObjects) { for (obj in dtsObjects) {
obj.update(timeState); obj.update(timeState);
} }
@ -1446,7 +1446,7 @@ class MarbleWorld extends Scheduler {
obj.update(timeState); obj.update(timeState);
} }
ProfilerUI.measure("updateMarbles"); ProfilerUI.measure("updateMarbles", 1);
marble.update(timeState, collisionWorld, this.pathedInteriors); marble.update(timeState, collisionWorld, this.pathedInteriors);
for (client => marble in clientMarbles) { for (client => marble in clientMarbles) {
marble.update(timeState, collisionWorld, this.pathedInteriors); marble.update(timeState, collisionWorld, this.pathedInteriors);
@ -1544,7 +1544,7 @@ class MarbleWorld extends Scheduler {
this.isReplayingMovement = false; this.isReplayingMovement = false;
} }
ProfilerUI.measure("updateTimer"); ProfilerUI.measure("updateTimer", 1);
this.updateTimer(dt); this.updateTimer(dt);
// if ((Key.isPressed(Settings.controlsSettings.respawn) || Gamepad.isPressed(Settings.gamepadSettings.respawn)) // if ((Key.isPressed(Settings.controlsSettings.respawn) || Gamepad.isPressed(Settings.gamepadSettings.respawn))
@ -1586,7 +1586,7 @@ class MarbleWorld extends Scheduler {
this.updateGameState(); this.updateGameState();
if (!this.isMultiplayer) if (!this.isMultiplayer)
this.updateBlast(this.marble, timeState); this.updateBlast(this.marble, timeState);
ProfilerUI.measure("updateDTS"); ProfilerUI.measure("updateDTS", 1);
for (obj in dtsObjects) { for (obj in dtsObjects) {
obj.update(timeState); obj.update(timeState);
} }
@ -1598,7 +1598,7 @@ class MarbleWorld extends Scheduler {
// inputRecorder.recordInput(timeState.currentAttemptTime); // inputRecorder.recordInput(timeState.currentAttemptTime);
// } // }
ProfilerUI.measure("updateMarbles"); ProfilerUI.measure("updateMarbles", 1);
if (this.isMultiplayer) { if (this.isMultiplayer) {
tickAccumulator += timeState.dt; tickAccumulator += timeState.dt;
while (tickAccumulator >= 0.032) { while (tickAccumulator >= 0.032) {
@ -1669,14 +1669,14 @@ class MarbleWorld extends Scheduler {
// Update camera separately // Update camera separately
marble.camera.update(timeState.currentAttemptTime, realDt); marble.camera.update(timeState.currentAttemptTime, realDt);
} }
ProfilerUI.measure("updateParticles"); ProfilerUI.measure("updateParticles", 1);
if (this.rewinding) { if (this.rewinding) {
this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt * rewindManager.timeScale); this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt * rewindManager.timeScale);
} else } else
this.particleManager.update(1000 * timeState.timeSinceLoad, dt); this.particleManager.update(1000 * timeState.timeSinceLoad, dt);
ProfilerUI.measure("updatePlayGui"); ProfilerUI.measure("updatePlayGui", 1);
this.playGui.update(timeState); this.playGui.update(timeState);
ProfilerUI.measure("updateAudio"); ProfilerUI.measure("updateAudio", 1);
AudioManager.update(this.scene); AudioManager.update(this.scene);
if (!this.isMultiplayer) { if (!this.isMultiplayer) {
@ -1713,10 +1713,10 @@ class MarbleWorld extends Scheduler {
if (_instancesNeedsUpdate) { if (_instancesNeedsUpdate) {
if (this.radar != null) if (this.radar != null)
this.radar.render(); this.radar.render();
ProfilerUI.measure("updateInstances"); ProfilerUI.measure("updateInstances", 0);
this.instanceManager.render(); this.instanceManager.render();
if (this.marble != null && this.marble.cubemapRenderer != null) { 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.position.load(this.marble.getAbsPos().getPosition());
this.marble.cubemapRenderer.render(e); this.marble.cubemapRenderer.render(e);

View file

@ -17,6 +17,7 @@ class ProfilerUI {
public static var instance:ProfilerUI; public static var instance:ProfilerUI;
static var enabled:Bool = false; static var enabled:Bool = false;
static var mode:Int = 0;
public function new(s2d:h2d.Scene) { public function new(s2d:h2d.Scene) {
if (instance != null) if (instance != null)
@ -26,22 +27,25 @@ class ProfilerUI {
this.s2d = s2d; this.s2d = s2d;
} }
public static function begin() { public static function begin(type:Int) {
if (!enabled) if (!enabled)
return; 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) if (!enabled)
return; return;
instance.debugProfiler.measure(name); if (type == mode)
instance.debugProfiler.measure(name);
} }
public static function end() { public static function end(type:Int) {
if (!enabled) if (!enabled)
return; return;
instance.debugProfiler.end(); if (type == mode)
instance.debugProfiler.end();
} }
public static function update(fps:Float) { public static function update(fps:Float) {
@ -77,6 +81,8 @@ class ProfilerUI {
instance.networkStats = new Text(DefaultFont.get(), instance.s2d); instance.networkStats = new Text(DefaultFont.get(), instance.s2d);
instance.networkStats.y = 150; instance.networkStats.y = 150;
instance.networkStats.color = new Vector(1, 1, 1, 1); instance.networkStats.color = new Vector(1, 1, 1, 1);
instance.debugProfiler.end(); // End current frame
} else { } else {
instance.debugProfiler.remove(); instance.debugProfiler.remove();
instance.fpsCounter.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() { static function updateNetworkStats() {
if (MarbleGame.instance.world != null && MarbleGame.instance.world.isMultiplayer) { if (MarbleGame.instance.world != null && MarbleGame.instance.world.isMultiplayer) {
static var lastSentMove = 0; static var lastSentMove = 0;

View file

@ -125,26 +125,26 @@ class Renderer extends h3d.scene.Renderer {
// ctx.engine.clear(0, 1); // ctx.engine.clear(0, 1);
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("sky"); ProfilerUI.measure("sky", 0);
if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 1) { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 1) {
renderPass(defaultPass, get("sky")); renderPass(defaultPass, get("sky"));
renderPass(defaultPass, get("skyshape"), backToFront); renderPass(defaultPass, get("skyshape"), backToFront);
} }
if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 2) { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 2) {
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("interiorZPass"); ProfilerUI.measure("interiorZPass", 0);
renderPass(defaultPass, get("zPass")); renderPass(defaultPass, get("zPass"));
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("interior"); ProfilerUI.measure("interior", 0);
renderPass(defaultPass, get("interior")); renderPass(defaultPass, get("interior"));
} }
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("render"); ProfilerUI.measure("render", 0);
if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 3) { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 3) {
renderPass(defaultPass, get("default")); renderPass(defaultPass, get("default"));
} }
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("glow"); ProfilerUI.measure("glow", 0);
if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4)
renderPass(defaultPass, get("glowPre")); renderPass(defaultPass, get("glowPre"));
@ -177,7 +177,7 @@ class Renderer extends h3d.scene.Renderer {
} }
} }
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("refract"); ProfilerUI.measure("refract", 0);
// Refraction pass // Refraction pass
if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) {
var refractObjects = get("refract"); var refractObjects = get("refract");
@ -189,7 +189,7 @@ class Renderer extends h3d.scene.Renderer {
} }
} }
if (!cubemapPass) if (!cubemapPass)
ProfilerUI.measure("alpha"); ProfilerUI.measure("alpha", 0);
if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) { if (!cubemapPass || Settings.optionsSettings.reflectionDetail >= 4) {
renderPass(defaultPass, get("alpha"), backToFront); renderPass(defaultPass, get("alpha"), backToFront);

View file

@ -6,7 +6,7 @@ import h3d.col.Bounds;
interface IBVHObject { interface IBVHObject {
var boundingBox:Bounds; var boundingBox:Bounds;
var key:Int; var key:Int;
function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<octree.IOctreeObject.RayIntersectionData>; function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>):Void;
} }
@:publicFields @:publicFields
@ -475,7 +475,7 @@ class BVHTree<T:IBVHObject> {
var currentnode = this.nodes[current]; var currentnode = this.nodes[current];
if (currentnode.collideRay(ray)) { if (currentnode.collideRay(ray)) {
if (currentnode.isLeaf) { if (currentnode.isLeaf) {
res = res.concat(currentnode.object.rayCast(origin, direction)); currentnode.object.rayCast(origin, direction, res);
} else { } else {
if (currentnode.child1 != -1) if (currentnode.child1 != -1)
q.push(currentnode.child1); q.push(currentnode.child1);

View file

@ -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<octree.IOctreeObject.RayIntersectionData>) {
// TEMP cause bruh // TEMP cause bruh
return [];
} }
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {

View file

@ -141,7 +141,7 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
} }
} }
public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData> { public function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<RayIntersectionData>) {
var invMatrix = invTransform; var invMatrix = invTransform;
var invTPos = invMatrix.clone(); var invTPos = invMatrix.clone();
invTPos.transpose(); invTPos.transpose();
@ -164,9 +164,8 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
i.point.transform(transform); i.point.transform(transform);
i.normal.transform3x3(invTPos); i.normal.transform3x3(invTPos);
i.normal.normalize(); i.normal.normalize();
results.push(i);
} }
return intersections;
// } // }
} }

View file

@ -139,8 +139,7 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
normals.push(z); normals.push(z);
} }
public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData> { public function rayCast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<RayIntersectionData>) {
var intersections:Array<RayIntersectionData> = [];
var i = 0; var i = 0;
while (i < indices.length) { while (i < indices.length) {
var p1 = getPoint(indices[i]); var p1 = getPoint(indices[i]);
@ -157,7 +156,6 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
} }
i += 3; i += 3;
} }
return intersections;
} }
public function support(direction:Vector, transform:Matrix) { public function support(direction:Vector, transform:Matrix) {

View file

@ -134,12 +134,19 @@ class CollisionWorld {
+ rayDirection.x * rayLength, rayStart.y + rayDirection.x * rayLength, rayStart.y
+ rayDirection.y * rayLength, rayStart.z + rayDirection.y * rayLength, rayStart.z
+ rayDirection.z * rayLength); + 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 = []; var results = [];
for (obj in objs) { 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; return results;
} }

View file

@ -175,7 +175,7 @@ class Grid {
if (surf.key == searchKey) if (surf.key == searchKey)
continue; continue;
surf.key = searchKey; surf.key = searchKey;
results = results.concat(surf.rayCast(origin, direction)); surf.rayCast(origin, direction, results);
} }
if (tmax.x < tmax.y) { if (tmax.x < tmax.y) {
X = X + stepX; X = X + stepX;

View file

@ -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<octree.IOctreeObject.RayIntersectionData>) {
// TEMP cause bruh // TEMP cause bruh
return [];
} }
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {

View file

@ -84,7 +84,7 @@ class GemOctreeElem implements IOctreeObject {
this.priority = priority; this.priority = priority;
} }
public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData> { public function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>) {
throw new haxe.exceptions.NotImplementedException(); // Not applicable throw new haxe.exceptions.NotImplementedException(); // Not applicable
} }
} }

View file

@ -13,5 +13,5 @@ class RayIntersectionData {
interface IOctreeObject extends IOctreeElement { interface IOctreeObject extends IOctreeElement {
var boundingBox:Bounds; var boundingBox:Bounds;
function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData>; function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>):Void;
} }

View file

@ -200,7 +200,8 @@ class OctreeNode implements IOctreeElement {
return; return;
for (obj in this.objects) { for (obj in this.objects) {
var iSecs = obj.rayCast(rayOrigin, rayDirection); var iSecs = [];
obj.rayCast(rayOrigin, rayDirection, iSecs);
for (intersection in iSecs) { for (intersection in iSecs) {
var intersectionData = new OctreeIntersection(); var intersectionData = new OctreeIntersection();
intersectionData.distance = rayOrigin.distance(intersection.point); intersectionData.distance = rayOrigin.distance(intersection.point);