reportFixture method
Called for each fixture found in the query AABB. Return false to terminate the query.
Implementation
@override
bool reportFixture(Fixture fixture) {
if (fixture.isSensor) {
return true;
}
final shape = fixture.shape;
final b = fixture.body;
final bp = b.worldCenter;
final bm = b.mass;
final bI = b.getInertia() - bm * b.getLocalCenter().length2;
final invBm = bm > 0 ? 1 / bm : 0.0;
final invBI = bI > 0 ? 1 / bI : 0.0;
final childCount = shape.childCount;
for (var childIndex = 0; childIndex < childCount; childIndex++) {
final aabb = fixture.getAABB(childIndex);
final aabbLowerBoundX = aabb.lowerBound.x - system.particleDiameter;
final aabbLowerBoundY = aabb.lowerBound.y - system.particleDiameter;
final aabbUpperBoundX = aabb.upperBound.x + system.particleDiameter;
final aabbUpperBoundY = aabb.upperBound.y + system.particleDiameter;
final firstProxy = ParticleSystem.lowerBound(
system.proxyBuffer,
ParticleSystem.computeTag(
system.inverseDiameter * aabbLowerBoundX,
system.inverseDiameter * aabbLowerBoundY,
),
);
final lastProxy = ParticleSystem.upperBound(
system.proxyBuffer,
ParticleSystem.computeTag(
system.inverseDiameter * aabbUpperBoundX,
system.inverseDiameter * aabbUpperBoundY,
),
);
for (var i = firstProxy; i < lastProxy; ++i) {
final particle = system.proxyBuffer[i].particle;
final ap = particle.position;
if (aabbLowerBoundX <= ap.x &&
ap.x <= aabbUpperBoundX &&
aabbLowerBoundY <= ap.y &&
ap.y <= aabbUpperBoundY) {
// _tempNormal gets manipulated here
final distance = fixture.computeDistance(ap, childIndex, _tempNormal);
if (distance < system.particleDiameter) {
final invAm = (particle.flags & ParticleType.wallParticle) != 0
? 0.0
: system.particleInverseMass;
final rpx = ap.x - bp.x;
final rpy = ap.y - bp.y;
final rpn = rpx * _tempNormal.y - rpy * _tempNormal.x;
final contact = ParticleBodyContact(particle, b)
..weight = 1 - distance * system.inverseDiameter
..normal.x = -_tempNormal.x
..normal.y = -_tempNormal.y
..mass = 1 / (invAm + invBm + invBI * rpn * rpn);
system.bodyContactBuffer.add(contact);
}
}
}
}
return true;
}