Esempio n. 1
0
  public void step(float dt, int iterations) {
    if (joint != null) {
      Vec2 force = joint.getReactionForce();
      float forceAngle = PhysicsUtils.angle(force);
      float forceMag = force.length();

      if (forceMag > reactionThreshold) {
        /*
         * First, check for direction.
         */
        if (angleLo == angleHi || (forceAngle >= angleLo && forceAngle <= angleHi)) {
          // Ok, this one's done with. Kill it.
          joint.getBody1().getWorld().destroyJoint(joint);
          joint = null;
          joint.getBody1().getWorld().unregisterPostStep(this);
        }
      }
    }
  }
Esempio n. 2
0
  @Override
  public void solveVelocityConstraints(TimeStep step) {
    Body b = m_bodyB;

    Vec2 r = pool.popVec2();

    r.set(m_localAnchor).subLocal(b.getLocalCenter());
    Mat22.mulToOut(b.getTransform().R, r, r);

    // Cdot = v + cross(w, r)
    Vec2 Cdot = pool.popVec2();
    Vec2.crossToOut(b.m_angularVelocity, r, Cdot);
    Cdot.addLocal(b.m_linearVelocity);

    Vec2 impulse = pool.popVec2();
    Vec2 temp = pool.popVec2();

    // Mul(m_mass, -(Cdot + m_beta * m_C + m_gamma * m_impulse));
    impulse.set(m_C).mulLocal(m_beta);
    temp.set(m_impulse).mulLocal(m_gamma);
    temp.addLocal(impulse).addLocal(Cdot).mulLocal(-1);
    Mat22.mulToOut(m_mass, temp, impulse);

    Vec2 oldImpulse = temp;
    oldImpulse.set(m_impulse);
    m_impulse.addLocal(impulse);
    float maxImpulse = step.dt * m_maxForce;
    if (m_impulse.lengthSquared() > maxImpulse * maxImpulse) {
      m_impulse.mulLocal(maxImpulse / m_impulse.length());
    }
    impulse.set(m_impulse).subLocal(oldImpulse);

    // pooling
    oldImpulse.set(impulse).mulLocal(b.m_invMass);
    b.m_linearVelocity.addLocal(oldImpulse);
    b.m_angularVelocity += b.m_invI * Vec2.cross(r, impulse);

    pool.pushVec2(4);
  }
Esempio n. 3
0
  @Override
  public boolean solvePositionConstraints(final org.jbox2d.dynamics.SolverData data) {
    final Rot qA = pool.popRot();
    final Rot qB = pool.popRot();
    Vec2 cA = data.positions[m_indexA].c;
    float aA = data.positions[m_indexA].a;
    Vec2 cB = data.positions[m_indexB].c;
    float aB = data.positions[m_indexB].a;

    qA.set(aA);
    qB.set(aB);

    float angularError = 0.0f;
    float positionError = 0.0f;

    boolean fixedRotation = (m_invIA + m_invIB == 0.0f);

    // Solve angular limit constraint.
    if (m_enableLimit && m_limitState != LimitState.INACTIVE && fixedRotation == false) {
      float angle = aB - aA - m_referenceAngle;
      float limitImpulse = 0.0f;

      if (m_limitState == LimitState.EQUAL) {
        // Prevent large angular corrections
        float C =
            MathUtils.clamp(
                angle - m_lowerAngle,
                -Settings.maxAngularCorrection,
                Settings.maxAngularCorrection);
        limitImpulse = -m_motorMass * C;
        angularError = MathUtils.abs(C);
      } else if (m_limitState == LimitState.AT_LOWER) {
        float C = angle - m_lowerAngle;
        angularError = -C;

        // Prevent large angular corrections and allow some slop.
        C = MathUtils.clamp(C + Settings.angularSlop, -Settings.maxAngularCorrection, 0.0f);
        limitImpulse = -m_motorMass * C;
      } else if (m_limitState == LimitState.AT_UPPER) {
        float C = angle - m_upperAngle;
        angularError = C;

        // Prevent large angular corrections and allow some slop.
        C = MathUtils.clamp(C - Settings.angularSlop, 0.0f, Settings.maxAngularCorrection);
        limitImpulse = -m_motorMass * C;
      }

      aA -= m_invIA * limitImpulse;
      aB += m_invIB * limitImpulse;
    }
    // Solve point-to-point constraint.
    {
      qA.set(aA);
      qB.set(aB);

      final Vec2 rA = pool.popVec2();
      final Vec2 rB = pool.popVec2();
      final Vec2 C = pool.popVec2();
      final Vec2 impulse = pool.popVec2();

      Rot.mulToOutUnsafe(qA, C.set(m_localAnchorA).subLocal(m_localCenterA), rA);
      Rot.mulToOutUnsafe(qB, C.set(m_localAnchorB).subLocal(m_localCenterB), rB);
      C.set(cB).addLocal(rB).subLocal(cA).subLocal(rA);
      positionError = C.length();

      float mA = m_invMassA, mB = m_invMassB;
      float iA = m_invIA, iB = m_invIB;

      final org.jbox2d.common.Mat22 K = pool.popMat22();
      K.ex.x = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y;
      K.ex.y = -iA * rA.x * rA.y - iB * rB.x * rB.y;
      K.ey.x = K.ex.y;
      K.ey.y = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x;
      K.solveToOut(C, impulse);
      impulse.negateLocal();

      cA.x -= mA * impulse.x;
      cA.y -= mA * impulse.y;
      aA -= iA * Vec2.cross(rA, impulse);

      cB.x += mB * impulse.x;
      cB.y += mB * impulse.y;
      aB += iB * Vec2.cross(rB, impulse);

      pool.pushVec2(4);
      pool.pushMat22(1);
    }
    // data.positions[m_indexA].c.set(cA);
    data.positions[m_indexA].a = aA;
    // data.positions[m_indexB].c.set(cB);
    data.positions[m_indexB].a = aB;

    pool.pushRot(2);

    return positionError <= Settings.linearSlop && angularError <= Settings.angularSlop;
  }