mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-22 02:32:01 +00:00
reduce array allocations when doing collision
This commit is contained in:
parent
95e75a220e
commit
a6ae9259a1
7 changed files with 44 additions and 87 deletions
|
|
@ -260,7 +260,8 @@ class Marble extends GameObject {
|
|||
|
||||
public var contacts:Array<CollisionInfo> = [];
|
||||
public var bestContact:CollisionInfo;
|
||||
public var contactEntities:Array<CollisionEntity> = [];
|
||||
|
||||
static var contactScratch:Array<CollisionEntity> = [];
|
||||
|
||||
var queuedContacts:Array<CollisionInfo> = [];
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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<CollisionInfo>) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<CollisionInfo>) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class CollisionHull extends CollisionEntity {
|
|||
super(go);
|
||||
}
|
||||
|
||||
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState):Array<CollisionInfo> {
|
||||
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState, contacts:Array<CollisionInfo>) {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -38,11 +38,12 @@ class CollisionWorld {
|
|||
this.dynamicGrid.build();
|
||||
}
|
||||
|
||||
public function sphereIntersection(spherecollision:SphereCollisionEntity, timeState:TimeState):SphereIntersectionResult {
|
||||
var contactList:Array<CollisionInfo> = [];
|
||||
var intersectionList:Array<CollisionEntity> = [];
|
||||
|
||||
public function sphereIntersection(spherecollision:SphereCollisionEntity, timeState:TimeState, contacts:Array<CollisionInfo>) {
|
||||
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<CollisionEntity>, 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ class GridBroadphase {
|
|||
}
|
||||
|
||||
// searchbox should be in LOCAL coordinates
|
||||
public function boundingSearch(searchbox:Bounds) {
|
||||
public function boundingSearch(searchbox:Bounds, foundSurfaces:Array<CollisionEntity>) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<CollisionInfo>) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue