/** @see Shape#computeSweptAABB(AABB, XForm, XForm) */
  @Override
  public void computeSweptAABB(final AABB aabb, final XForm transform1, final XForm transform2) {
    // djm this method is pretty hot (called every time step)
    final Vec2 sweptV1 = tlSwept1.get();
    final Vec2 sweptV2 = tlSwept2.get();
    final Vec2 sweptV3 = tlSwept3.get();
    final Vec2 sweptV4 = tlSwept4.get();

    XForm.mulToOut(transform1, m_v1, sweptV1);
    XForm.mulToOut(transform1, m_v2, sweptV2);
    XForm.mulToOut(transform2, m_v1, sweptV3);
    XForm.mulToOut(transform2, m_v2, sweptV4);

    // aabb.lowerBound = Vec2.min(Vec2.min(Vec2.min(v1, v2), v3), v4);
    // aabb.upperBound = Vec2.max(Vec2.max(Vec2.max(v1, v2), v3), v4);

    // djm ok here's the non object-creation-crazy way
    Vec2.minToOut(sweptV1, sweptV2, aabb.lowerBound);
    Vec2.minToOut(aabb.lowerBound, sweptV3, aabb.lowerBound);
    Vec2.minToOut(aabb.lowerBound, sweptV4, aabb.lowerBound);

    Vec2.maxToOut(sweptV1, sweptV2, aabb.upperBound);
    Vec2.maxToOut(aabb.upperBound, sweptV3, aabb.upperBound);
    Vec2.maxToOut(aabb.upperBound, sweptV4, aabb.upperBound);
  }
  @Override
  public final void computeAABB(final AABB aabb, final Transform xf, int childIndex) {
    final Vec2 v = pool1;
    final Vec2 lower = aabb.lowerBound;
    final Vec2 upper = aabb.upperBound;
    final Vec2 v1 = m_vertices[0];
    lower.x = (xf.q.c * v1.x - xf.q.s * v1.y) + xf.p.x;
    lower.y = (xf.q.s * v1.x + xf.q.c * v1.y) + xf.p.y;
    upper.set(lower);

    for (int i = 1; i < m_count; ++i) {
      Vec2 v2 = m_vertices[i];
      v.x = (xf.q.c * v2.x - xf.q.s * v2.y) + xf.p.x;
      v.y = (xf.q.s * v2.x + xf.q.c * v2.y) + xf.p.y;
      // Vec2 v = Mul(xf, m_vertices[i]);
      Vec2.minToOut(lower, v, lower);
      Vec2.maxToOut(upper, v, upper);
    }

    // Vec2 r(m_radius, m_radius);
    // aabb.lowerBound = lower - r;
    // aabb.upperBound = upper + r;

    aabb.lowerBound.x -= m_radius;
    aabb.lowerBound.y -= m_radius;
    aabb.upperBound.x += m_radius;
    aabb.upperBound.y += m_radius;
  }
  /** @see Shape#computeAABB(AABB, XForm) */
  @Override
  public void computeAABB(final AABB aabb, final XForm transform) {
    /*Vec2 v1 = XForm.mul(transform, m_v1);
    Vec2 v2 = XForm.mul(transform, m_v2);
    aabb.lowerBound = Vec2.min(v1, v2);
    aabb.upperBound = Vec2.max(v1, v2);*/

    // djm we avoid one creation. crafty huh?
    XForm.mulToOut(transform, m_v1, aabb.lowerBound);
    final Vec2 v2 = tlV2.get();
    XForm.mulToOut(transform, m_v2, v2);

    Vec2.maxToOut(aabb.lowerBound, v2, aabb.upperBound);
    Vec2.minToOut(aabb.lowerBound, v2, aabb.lowerBound);
  }