reportFixture method

  1. @override
bool reportFixture(
  1. Fixture fixture
)
override

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;
}