createParticleGroup method

ParticleGroup createParticleGroup(
  1. ParticleGroupDef groupDef
)

Implementation

ParticleGroup createParticleGroup(ParticleGroupDef groupDef) {
  final stride = particleStride;
  final identity = _tempTransform..setIdentity();
  final transform = _tempTransform2..setIdentity();

  final group = ParticleGroup(this)
    ..groupFlags = groupDef.groupFlags
    ..strength = groupDef.strength
    ..userData = groupDef.userData
    ..transform.setFrom(transform)
    ..destroyAutomatically = groupDef.destroyAutomatically;

  if (groupDef.shape != null) {
    final seedParticle = Particle(this, group: group)
      ..flags = groupDef.flags
      ..color = groupDef.color
      ..userData = groupDef.userData;
    final shape = groupDef.shape;
    transform.setVec2Angle(groupDef.position, groupDef.angle);
    final aabb = _temp;
    final childCount = shape!.childCount;
    for (var childIndex = 0; childIndex < childCount; childIndex++) {
      if (childIndex == 0) {
        shape.computeAABB(aabb, identity, childIndex);
      } else {
        final childAABB = _temp2;
        shape.computeAABB(childAABB, identity, childIndex);
        aabb.combine(childAABB);
      }
    }
    final upperBoundY = aabb.upperBound.y;
    final upperBoundX = aabb.upperBound.x;
    for (var y = (aabb.lowerBound.y / stride).floor() * stride;
        y < upperBoundY;
        y += stride) {
      for (var x = (aabb.lowerBound.x / stride).floor() * stride;
          x < upperBoundX;
          x += stride) {
        final p = _tempVec..setValues(x, y);
        if (shape.testPoint(identity, p)) {
          p.setFrom(Transform.mulVec2(transform, p));
          final particle = seedParticle.clone();
          particle.position.setFrom(p);
          p.scaleOrthogonalInto(
            groupDef.angularVelocity,
            particle.velocity,
          );
          particle.velocity.add(groupDef.linearVelocity);
          createParticle(particle);
        }
      }
    }
    groupBuffer.add(group);
  }

  updateContacts();
  if ((groupDef.flags & pairFlags) != 0) {
    for (final contact in contactBuffer) {
      final particleA = contact.particleA;
      final particleB = contact.particleB;
      if (group.particles.contains(particleA) &&
          group.particles.contains(particleB)) {
        final pair = PsPair(particleA, particleB)
          ..flags = contact.flags
          ..strength = groupDef.strength
          ..distance = particleA.position.distanceTo(particleB.position);
        pairBuffer.add(pair);
      }
    }
  }
  if ((groupDef.flags & triadFlags) != 0) {
    final diagram = VoronoiDiagram();
    for (final particle in group.particles) {
      diagram.addGenerator(particle.position, particle);
    }
    diagram.generate(stride / 2);
    final createParticleGroupCallback =
        CreateParticleGroupCallback(this, groupDef);
    diagram.nodes(createParticleGroupCallback);
  }
  if ((groupDef.groupFlags & ParticleGroupType.solidParticleGroup) != 0) {
    computeDepthForGroup(group);
  }

  return group;
}