mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
add profiler modes and improve alloc in raycasts
This commit is contained in:
parent
a0ee2f1398
commit
45add5e0d4
16 changed files with 74 additions and 48 deletions
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
10
src/Main.hx
10
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() {
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ class MarbleGame {
|
|||
wheel: _mouseWheelDelta,
|
||||
handled: false
|
||||
}
|
||||
ProfilerUI.measure("canvasUpdate");
|
||||
ProfilerUI.measure("canvasUpdate", 1);
|
||||
canvas.update(dt, mouseState);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import h3d.col.Bounds;
|
|||
interface IBVHObject {
|
||||
var boundingBox:Bounds;
|
||||
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
|
||||
|
|
@ -475,7 +475,7 @@ class BVHTree<T:IBVHObject> {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
return [];
|
||||
}
|
||||
|
||||
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {
|
||||
|
|
|
|||
|
|
@ -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 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;
|
||||
// }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -139,8 +139,7 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
|
|||
normals.push(z);
|
||||
}
|
||||
|
||||
public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData> {
|
||||
var intersections:Array<RayIntersectionData> = [];
|
||||
public function rayCast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<RayIntersectionData>) {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
return [];
|
||||
}
|
||||
|
||||
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class GemOctreeElem implements IOctreeObject {
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,5 +13,5 @@ class RayIntersectionData {
|
|||
|
||||
interface IOctreeObject extends IOctreeElement {
|
||||
var boundingBox:Bounds;
|
||||
function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData>;
|
||||
function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>):Void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue