diff --git a/src/Marble.hx b/src/Marble.hx index 43f7845f..10f3d4ee 100644 --- a/src/Marble.hx +++ b/src/Marble.hx @@ -260,7 +260,8 @@ class Marble extends GameObject { public var contacts:Array = []; public var bestContact:CollisionInfo; - public var contactEntities:Array = []; + + static var contactScratch:Array = []; var queuedContacts:Array = []; var appliedImpulses:Array<{impulse:Vector, contactImpulse:Bool}> = []; @@ -700,9 +701,7 @@ class Marble extends GameObject { function findContacts(collisiomWorld:CollisionWorld, timeState:TimeState) { this.contacts = queuedContacts; CollisionPool.clear(); - var c = collisiomWorld.sphereIntersection(this.collider, timeState); - this.contactEntities = c.foundEntities; - contacts = contacts.concat(c.contacts); + collisiomWorld.sphereIntersection(this.collider, timeState, this.contacts); } public function queueCollision(collisionInfo:CollisionInfo) { @@ -1274,7 +1273,10 @@ class Marble extends GameObject { searchbox.addSpherePos(position.x, position.y, position.z, _radius); searchbox.addSpherePos(position.x + velocity.x * deltaT, position.y + velocity.y * deltaT, position.z + velocity.z * deltaT, _radius); - var foundObjs = this.collisionWorld.boundingSearch(searchbox); + contactScratch.resize(0); + this.collisionWorld.boundingSearch(searchbox, contactScratch); + + var foundObjs = contactScratch; var finalT = deltaT; var found = false; @@ -1904,7 +1906,7 @@ class Marble extends GameObject { } // } } - this.queuedContacts = []; + this.queuedContacts.resize(0); newPos = this.collider.transform.getPosition(); // this.getAbsPos().getPosition().clone(); @@ -1983,7 +1985,9 @@ class Marble extends GameObject { // marbleHitbox.offset(end.x, end.y, end.z); // spherebounds.addSpherePos(gjkCapsule.p2.x, gjkCapsule.p2.y, gjkCapsule.p2.z, gjkCapsule.radius); - var contacts = this.collisionWorld.boundingSearch(box); + contactScratch.resize(0); + this.collisionWorld.boundingSearch(box, contactScratch); + var contacts = contactScratch; // var contacts = marble.contactEntities; var inside = []; @@ -2036,7 +2040,9 @@ class Marble extends GameObject { var checkSphereRadius = checkBounds.getMax().sub(checkBoundsCenter).length(); var checkSphere = new Bounds(); checkSphere.addSpherePos(checkBoundsCenter.x, checkBoundsCenter.y, checkBoundsCenter.z, checkSphereRadius); - var endpadBB = this.collisionWorld.boundingSearch(checkSphere, false); + contactScratch.resize(0); + this.collisionWorld.boundingSearch(checkSphere, contactScratch, false); + var endpadBB = contactScratch; var found = false; for (collider in endpadBB) { if (collider.go == @:privateAccess this.level.endPad) { @@ -2820,7 +2826,6 @@ class Marble extends GameObject { this.megaMarbleUseTick = 0; this.netFlags = MarbleNetFlags.DoBlast | MarbleNetFlags.DoMega | MarbleNetFlags.DoHelicopter | MarbleNetFlags.DoShockAbsorber | MarbleNetFlags.DoSuperBounce | MarbleNetFlags.PickupPowerup | MarbleNetFlags.GravityChange | MarbleNetFlags.UsePowerup; this.lastContactNormal = new Vector(0, 0, 1); - this.contactEntities = []; this.cloak = false; this._firstTick = true; this.lastRespawnTick = -100000; diff --git a/src/collision/BoxCollisionEntity.hx b/src/collision/BoxCollisionEntity.hx index f017034d..a4501e03 100644 --- a/src/collision/BoxCollisionEntity.hx +++ b/src/collision/BoxCollisionEntity.hx @@ -56,7 +56,5 @@ class BoxCollisionEntity extends CollisionEntity implements IBVHObject { return Math.POSITIVE_INFINITY; } - public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { - return []; - } + public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState, contacts:Array) {} } diff --git a/src/collision/CollisionEntity.hx b/src/collision/CollisionEntity.hx index b6c01f02..40dc552b 100644 --- a/src/collision/CollisionEntity.hx +++ b/src/collision/CollisionEntity.hx @@ -200,7 +200,7 @@ class CollisionEntity implements IOctreeObject implements IBVHObject { this.priority = priority; } - public function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { + public function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState, contacts:Array) { var position = collisionEntity.transform.getPosition(); var radius = collisionEntity.radius + 0.001; @@ -227,8 +227,6 @@ class CollisionEntity implements IOctreeObject implements IBVHObject { invtform.load(Matrix.I()); } - var contacts = []; - for (obj in surfaces) { var surface:CollisionSurface = cast obj; @@ -301,7 +299,5 @@ class CollisionEntity implements IOctreeObject implements IBVHObject { // if (surfaceBestContact != null) // contacts.push(surfaceBestContact); } - - return contacts; } } diff --git a/src/collision/CollisionHull.hx b/src/collision/CollisionHull.hx index 3b8bdd17..604e0be8 100644 --- a/src/collision/CollisionHull.hx +++ b/src/collision/CollisionHull.hx @@ -18,7 +18,7 @@ class CollisionHull extends CollisionEntity { super(go); } - public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState):Array { + public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState, contacts:Array) { var bbox = this.boundingBox; var box = new Bounds(); var pos = collisionEntity.transform.getPosition(); @@ -51,10 +51,9 @@ class CollisionHull extends CollisionEntity { cinfo.friction = friction; cinfo.force = force; this.go.onMarbleContact(collisionEntity.marble, timeState, cinfo); - return [cinfo]; + contacts.push(cinfo); } } - return []; } public override function addSurface(surface:CollisionSurface) { diff --git a/src/collision/CollisionWorld.hx b/src/collision/CollisionWorld.hx index f624c004..9f07adb0 100644 --- a/src/collision/CollisionWorld.hx +++ b/src/collision/CollisionWorld.hx @@ -38,11 +38,12 @@ class CollisionWorld { this.dynamicGrid.build(); } - public function sphereIntersection(spherecollision:SphereCollisionEntity, timeState:TimeState):SphereIntersectionResult { + var contactList:Array = []; + var intersectionList:Array = []; + + public function sphereIntersection(spherecollision:SphereCollisionEntity, timeState:TimeState, contacts:Array) { var position = spherecollision.transform.getPosition(); var radius = spherecollision.radius; - // var velocity = spherecollision.velocity; - // var intersections = this.octree.radiusSearch(position, searchdist); var box = new Bounds(); box.addSpherePos(0, 0, 0, radius); @@ -50,60 +51,24 @@ class CollisionWorld { box.transform(rotQuat.toMatrix()); box.offset(position.x, position.y, position.z); // box.addSpherePos(position.x + velocity.x * timeState.dt, position.y + velocity.y * timeState.dt, position.z + velocity.z * timeState.dt, radius); - var intersections = this.grid.boundingSearch(box); + this.intersectionList.resize(0); + this.grid.boundingSearch(box, this.intersectionList); + dynamicGrid.boundingSearch(box, this.intersectionList); - // 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)); - } - } - - // if (marbleEntities.length > 1) { - // marbleSap.recompute(); - // var sapCollisions = marbleSap.getIntersections(spherecollision); - // for (obj in sapCollisions) { - // if (obj.go.isCollideable) { - // contacts = contacts.concat(obj.sphereIntersection(spherecollision, timeState)); - // } - // } - // } - - // contacts = contacts.concat(this.staticWorld.sphereIntersection(spherecollision, timeState)); - - var dynSearch = dynamicGrid.boundingSearch(box); - for (obj in dynSearch) { + for (obj in this.intersectionList) { if (obj != spherecollision) { - var col = cast(obj, CollisionEntity); - if (col.boundingBox.collide(box) && col.go.isCollideable) - contacts = contacts.concat(col.sphereIntersection(spherecollision, timeState)); + var entity = obj; + + if (obj.boundingBox.collide(box) && entity.go.isCollideable) { + entity.sphereIntersection(spherecollision, timeState, contacts); + } } } - - // for (marb in marbleEntities) { - // if (marb != spherecollision) { - // if (spherecollision.go.isCollideable) { - // var isecs = marb.sphereIntersection(spherecollision, timeState); - // if (isecs.length > 0) - // foundEntities.push(marb); - // contacts = contacts.concat(isecs); - // } - // } - // } - return {foundEntities: foundEntities, contacts: contacts}; } - public function boundingSearch(bounds:Bounds, useCache:Bool = true) { - var contacts = this.grid.boundingSearch(bounds).map(x -> cast(x, CollisionEntity)); - contacts = contacts.concat(dynamicGrid.boundingSearch(bounds).map(x -> cast(x, CollisionEntity))); - return contacts; + public function boundingSearch(bounds:Bounds, contacts:Array, useCache:Bool = true) { + this.grid.boundingSearch(bounds, contacts); + dynamicGrid.boundingSearch(bounds, contacts); } public function rayCast(rayStart:Vector, rayDirection:Vector, rayLength:Float) { @@ -116,19 +81,17 @@ class CollisionWorld { + rayDirection.x * rayLength, rayStart.y + rayDirection.y * rayLength, rayStart.z + rayDirection.z * rayLength); - var objs = this.grid.boundingSearch(bounds); - var dynObjs = dynamicGrid.boundingSearch(bounds); + this.intersectionList.splice(0, this.intersectionList.length); + + this.grid.boundingSearch(bounds, this.intersectionList); + dynamicGrid.boundingSearch(bounds, this.intersectionList); + var results = []; - for (obj in objs) { - var oo = cast(obj, CollisionEntity); + for (obj in this.intersectionList) { + var oo = obj; oo.rayCast(rayStart, rayDirection, results, rayLength); } - for (obj in dynObjs) { - var oo = cast(obj, CollisionEntity); - oo.rayCast(rayStart, rayDirection, results, rayLength); - } - // results = results.concat(this.staticWorld.rayCast(rayStart, rayDirection)); return results; } diff --git a/src/collision/GridBroadphase.hx b/src/collision/GridBroadphase.hx index 557ea77a..2921fe4e 100644 --- a/src/collision/GridBroadphase.hx +++ b/src/collision/GridBroadphase.hx @@ -221,7 +221,7 @@ class GridBroadphase { } // searchbox should be in LOCAL coordinates - public function boundingSearch(searchbox:Bounds) { + public function boundingSearch(searchbox:Bounds, foundSurfaces:Array) { var queryMinX = Math.max(searchbox.xMin, bounds.xMin); var queryMinY = Math.max(searchbox.yMin, bounds.yMin); var queryMaxX = Math.min(searchbox.xMax, bounds.xMax); @@ -240,8 +240,6 @@ class GridBroadphase { if (yEnd > CELL_SIZE) yEnd = CELL_SIZE; - var foundSurfaces = []; - searchKey++; // Insert the surface references from [xStart, yStart, zStart] to [xEnd, yEnd, zEnd] into the map diff --git a/src/collision/SphereCollisionEntity.hx b/src/collision/SphereCollisionEntity.hx index 06892285..a050396c 100644 --- a/src/collision/SphereCollisionEntity.hx +++ b/src/collision/SphereCollisionEntity.hx @@ -75,10 +75,9 @@ class SphereCollisionEntity extends CollisionEntity { return Math.POSITIVE_INFINITY; } - public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) { + public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState, contacts:Array) { if (ignore) - return []; - var contacts = []; + return; var thispos = transform.getPosition(); var position = collisionEntity.transform.getPosition(); var velocity = collisionEntity.velocity; @@ -113,6 +112,5 @@ class SphereCollisionEntity extends CollisionEntity { // othercontact.penetration = this.radius - (thispos.sub(othercontact.point).dot(othercontact.normal)); // this.marble.queueCollision(othercontact); } - return contacts; } }