From 9f226a4f5da04cf2261b8200000be4303954cc69 Mon Sep 17 00:00:00 2001 From: RandomityGuy <31925790+RandomityGuy@users.noreply.github.com> Date: Thu, 17 Jun 2021 14:05:24 +0530 Subject: [PATCH] speed up some octree crap --- src/DtsObject.hx | 22 +++++++++++++++++++--- src/GameObject.hx | 1 + src/Main.hx | 2 +- src/Marble.hx | 23 +++++++++++++++-------- src/MarbleWorld.hx | 6 ++++-- src/collision/CollisionEntity.hx | 2 ++ src/collision/CollisionWorld.hx | 22 ++++++++++++++++++++-- src/octree/Octree.hx | 6 ++++++ src/octree/OctreeNode.hx | 16 ++++++++++++++++ src/shapes/TimeTravel.hx | 4 +++- 10 files changed, 87 insertions(+), 17 deletions(-) diff --git a/src/DtsObject.hx b/src/DtsObject.hx index e9749c08..448eb5d8 100644 --- a/src/DtsObject.hx +++ b/src/DtsObject.hx @@ -83,6 +83,7 @@ class DtsObject extends GameObject { var lastSequenceKeyframes:Map = new Map(); var graphNodes:Array = []; + var dirtyTransforms:Array = []; var useInstancing:Bool = true; var isTSStatic:Bool; @@ -302,6 +303,11 @@ class DtsObject extends GameObject { this.boundingCollider = new BoxCollisionEntity(this.level.instanceManager.getObjectBounds(cast this), cast this); this.boundingCollider.setTransform(this.getTransform()); } + + this.dirtyTransforms = []; + for (i in 0...graphNodes.length) { + this.dirtyTransforms.push(true); + } } function computeMaterials() { @@ -570,6 +576,9 @@ class DtsObject extends GameObject { super.setTransform(mat); this.boundingCollider.setTransform(mat); this.level.collisionWorld.updateTransform(this.boundingCollider); + for (i in 0...this.dirtyTransforms.length) { + this.dirtyTransforms[i] = true; + } } public function update(timeState:TimeState) { @@ -619,6 +628,7 @@ class DtsObject extends GameObject { quat.normalize(); this.graphNodes[i].setRotationQuat(quat); + this.dirtyTransforms[i] = true; affectedCount++; // quaternions.push(quat); } else { @@ -647,6 +657,7 @@ class DtsObject extends GameObject { var v2 = new Vector(trans2.x, trans2.y, trans2.z); var trans = Util.lerpThreeVectors(v1, v2, t); this.graphNodes[i].setPosition(trans.x, trans.y, trans.z); + this.dirtyTransforms[i] = true; // translations.push(Util.lerpThreeVectors(v1, v2, t)); } else { @@ -782,9 +793,14 @@ class DtsObject extends GameObject { } for (i in 0...this.colliders.length) { - var absTform = this.graphNodes[this.colliders[i].userData].getAbsPos().clone(); - if (this.colliders[i] != null) - this.colliders[i].setTransform(absTform); + if (this.dirtyTransforms[this.colliders[i].userData]) { + var absTform = this.graphNodes[this.colliders[i].userData].getAbsPos().clone(); + if (this.colliders[i] != null) + this.colliders[i].setTransform(absTform); + } + } + for (i in 0...this.dirtyTransforms.length) { + this.dirtyTransforms[i] = false; } } diff --git a/src/GameObject.hx b/src/GameObject.hx index 47f28df6..f2e222c4 100644 --- a/src/GameObject.hx +++ b/src/GameObject.hx @@ -8,6 +8,7 @@ class GameObject extends Object { public var identifier:String; public var currentOpacity:Float = 1; public var isCollideable:Bool = false; + public var isBoundingBoxCollideable:Bool = true; public function onMarbleContact(time:TimeState, ?contact:CollisionInfo) {} diff --git a/src/Main.hx b/src/Main.hx index b4943bfb..849f09f5 100644 --- a/src/Main.hx +++ b/src/Main.hx @@ -52,7 +52,7 @@ class Main extends hxd.App { override function init() { super.init(); - var ltr = File.getContent("data/missions/advanced/survival.mis"); + var ltr = File.getContent("data/missions/advanced/airwalk.mis"); var mfp = new MisParser(ltr); var mis = mfp.parse(); diff --git a/src/Marble.hx b/src/Marble.hx index 27242adb..cf45dec8 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -1,5 +1,7 @@ package src; +import h3d.col.Bounds; +import collision.CollisionEntity; import shapes.StartPad; import src.TimeState; import src.ParticleSystem.ParticleEmitter; @@ -132,7 +134,9 @@ class Marble extends GameObject { public var _mass:Float = 1; - var contacts:Array = []; + public var contacts:Array = []; + public var contactEntities:Array = []; + var queuedContacts:Array = []; public var heldPowerup:PowerUp; @@ -189,6 +193,7 @@ class Marble extends GameObject { this.forcefield.x = 1e8; this.forcefield.y = 1e8; this.forcefield.z = 1e8; + this.forcefield.isBoundingBoxCollideable = false; level.addDtsObject(this.forcefield); this.helicopter = new DtsObject(); @@ -196,6 +201,7 @@ class Marble extends GameObject { this.helicopter.useInstancing = true; this.helicopter.identifier = "Helicopter"; this.helicopter.showSequences = true; + this.helicopter.isBoundingBoxCollideable = false; // this.addChild(this.helicopter); this.helicopter.x = 1e8; this.helicopter.y = 1e8; @@ -206,7 +212,8 @@ class Marble extends GameObject { function findContacts(collisiomWorld:CollisionWorld, timeState:TimeState) { this.contacts = queuedContacts; var c = collisiomWorld.sphereIntersection(this.collider, timeState); - contacts = contacts.concat(c); + this.contactEntities = c.foundEntities; + contacts = contacts.concat(c.contacts); } public function queueCollision(collisionInfo:CollisionInfo) { @@ -597,13 +604,13 @@ class Marble extends GameObject { } function getIntersectionTime(dt:Float, velocity:Vector) { - var expandedcollider = new SphereCollisionEntity(cast this); + var searchbox = new Bounds(); + searchbox.addSpherePos(this.x, this.y, this.z, _radius); + searchbox.addSpherePos(this.x + velocity.x * dt, this.y + velocity.y * dt, this.z + velocity.z * dt, _radius); + var position = this.getAbsPos().getPosition(); - expandedcollider.transform = Matrix.T(position.x, position.y, position.z); - expandedcollider.radius = velocity.multiply(dt).length() + _radius; - - var foundObjs = this.level.collisionWorld.radiusSearch(position, expandedcollider.radius); + var foundObjs = this.level.collisionWorld.boundingSearch(searchbox); function toDifPoint(vec:Vector) { return new Point3F(vec.x, vec.y, vec.z); @@ -612,7 +619,7 @@ class Marble extends GameObject { var intersectT = 10e8; for (obj in foundObjs) { - var radius = expandedcollider.radius; + var radius = _radius; var invMatrix = obj.transform.clone(); invMatrix.invert(); diff --git a/src/MarbleWorld.hx b/src/MarbleWorld.hx index d8b53c5f..da15a6ca 100644 --- a/src/MarbleWorld.hx +++ b/src/MarbleWorld.hx @@ -569,7 +569,8 @@ class MarbleWorld extends Scheduler { if (collider != null) this.collisionWorld.addEntity(collider); } - this.collisionWorld.addEntity(obj.boundingCollider); + if (obj.isBoundingBoxCollideable) + this.collisionWorld.addEntity(obj.boundingCollider); } public function addMarble(marble:Marble) { @@ -683,7 +684,8 @@ class MarbleWorld extends Scheduler { } public function callCollisionHandlers(marble:Marble, timeState:TimeState) { - var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius); + // var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius); + var contacts = marble.contactEntities; var newImmunity = []; var calledShapes = []; var inside = []; diff --git a/src/collision/CollisionEntity.hx b/src/collision/CollisionEntity.hx index 3e5a2de4..061876d0 100644 --- a/src/collision/CollisionEntity.hx +++ b/src/collision/CollisionEntity.hx @@ -43,6 +43,8 @@ class CollisionEntity implements IOctreeObject { } public function setTransform(transform:Matrix) { + if (this.transform == transform) + return; this.transform = transform; generateBoundingBox(); } diff --git a/src/collision/CollisionWorld.hx b/src/collision/CollisionWorld.hx index 8175da57..626486da 100644 --- a/src/collision/CollisionWorld.hx +++ b/src/collision/CollisionWorld.hx @@ -20,7 +20,7 @@ class CollisionWorld { var radius = spherecollision.radius; var velocity = spherecollision.velocity; var searchdist = (velocity.length() * timeState.dt) + radius; - var intersections = this.octree.radiusSearch(position, searchdist); + // var intersections = this.octree.radiusSearch(position, searchdist); var box = new Bounds(); box.xMin = position.x - radius; @@ -29,12 +29,17 @@ class CollisionWorld { box.xMax = position.x + radius; box.yMax = position.y + radius; box.zMax = position.z + radius; + var intersections = this.octree.boundingSearch(box); + + // var intersections = this.rtree.search([box.xMin, box.yMax, box.zMin], [box.xSize, box.ySize, box.zSize]); var contacts = []; + var foundEntities = []; for (obj in intersections) { var entity:CollisionEntity = cast obj; + foundEntities.push(entity); if (entity.go.isCollideable) { contacts = contacts.concat(entity.sphereIntersection(spherecollision, timeState)); } @@ -46,7 +51,7 @@ class CollisionWorld { contacts = contacts.concat(obj.sphereIntersection(spherecollision, timeState)); } } - return contacts; + return {foundEntities: foundEntities, contacts: contacts}; } public function radiusSearch(center:Vector, radius:Float) { @@ -76,13 +81,26 @@ class CollisionWorld { return contacts; } + public function boundingSearch(bounds:Bounds) { + var contacts = this.octree.boundingSearch(bounds).map(x -> cast(x, CollisionEntity)); + for (obj in dynamicEntities) { + if (obj.boundingBox.collide(bounds)) + contacts.push(obj); + } + return contacts; + } + public function rayCast(rayStart:Vector, rayDirection:Vector) { + return []; return this.octree.raycast(rayStart, rayDirection); } public function addEntity(entity:CollisionEntity) { this.octree.insert(entity); this.entities.push(entity); + + // this.rtree.insert([entity.boundingBox.xMin, entity.boundingBox.yMin, entity.boundingBox.zMin], + // [entity.boundingBox.xSize, entity.boundingBox.ySize, entity.boundingBox.zSize], entity); } public function addMovingEntity(entity:CollisionEntity) { diff --git a/src/octree/Octree.hx b/src/octree/Octree.hx index ab896b6c..c81fe487 100644 --- a/src/octree/Octree.hx +++ b/src/octree/Octree.hx @@ -131,6 +131,12 @@ class Octree { return intersections; } + public function boundingSearch(bounds:Bounds) { + var intersections = []; + this.root.boundingSearch(bounds, intersections); + return intersections; + } + public function radiusSearch(point:Vector, maximumDistance:Float) { function getClosestPoint(box:Bounds, point:Vector) { var closest = new Vector(); diff --git a/src/octree/OctreeNode.hx b/src/octree/OctreeNode.hx index 16680f45..306ff8a3 100644 --- a/src/octree/OctreeNode.hx +++ b/src/octree/OctreeNode.hx @@ -185,6 +185,22 @@ class OctreeNode implements IOctreeElement { } } + public function boundingSearch(bounds:Bounds, intersections:Array) { + var thisBounds = new Bounds(); + thisBounds.setMin(this.min.toPoint()); + thisBounds.xSize = thisBounds.ySize = thisBounds.zSize = this.size; + if (thisBounds.collide(bounds)) { + for (obj in this.objects) { + if (obj.boundingBox.collide(bounds)) + intersections.push(obj); + } + if (octants != null) { + for (octant in this.octants) + octant.boundingSearch(bounds, intersections); + } + } + } + public function getClosestPoint(point:Vector) { var closest = new Vector(); if (this.min.x > point.x) diff --git a/src/shapes/TimeTravel.hx b/src/shapes/TimeTravel.hx index ccc17070..2c1a6247 100644 --- a/src/shapes/TimeTravel.hx +++ b/src/shapes/TimeTravel.hx @@ -28,5 +28,7 @@ class TimeTravel extends PowerUp { return true; } - public function use(time:TimeState) {} + public function use(time:TimeState) { + level.bonusTime += this.timeBonus; + } }