示例#1
0
  @Test
  public void testMomentumTransferFactor() throws Exception {
    int iterationCountPerStep = Defaults.ITERATION_COUNT_PER_STEP;
    int stepCountPerTimeUnit = 1;

    double originalVelocityModule = 0.1D;

    World world = new World(iterationCountPerStep, stepCountPerTimeUnit);

    Body bodyA = new Body();
    bodyA.setForm(new CircularForm(1.0D));
    bodyA.setMass(1.0D);
    bodyA.setMomentumTransferFactor(0.5D);
    world.addBody(bodyA);

    bodyA.setPosition(0.0D, 0.0D);
    bodyA.setVelocity(originalVelocityModule, 0.0D);

    Body bodyB = new Body();
    bodyB.setForm(new CircularForm(1.0D));
    bodyB.setMass(1.0D);
    bodyB.setMomentumTransferFactor(0.5D);
    world.addBody(bodyB);

    bodyB.setPosition(3.0D, 0.0D);
    bodyB.setVelocity(-originalVelocityModule, 0.0D);

    for (int i = 1; i <= 10; ++i) {
      world.proceed();
    }

    Assert.assertEquals(
        "Inelastic collision test. Illegal speed module "
            + bodyA.getVelocity().getLength()
            + " of body A.",
        originalVelocityModule
            * bodyA.getMomentumTransferFactor()
            * bodyB.getMomentumTransferFactor(),
        bodyA.getVelocity().getLength(),
        Defaults.EPSILON);

    Assert.assertEquals(
        "Inelastic collision test. Illegal speed module "
            + bodyB.getVelocity().getLength()
            + " of body B.",
        originalVelocityModule
            * bodyA.getMomentumTransferFactor()
            * bodyB.getMomentumTransferFactor(),
        bodyB.getVelocity().getLength(),
        Defaults.EPSILON);
  }
  /** Resets the widget to start state. */
  public void resetWidget() {
    // Reset has been made, so we CAN activate this later.
    reset = true;
    // Make inactive
    active = false;
    // Not collided.
    collided = false;

    bounces = 0;
    currentDirection = direction;
    image = frames.get(0);
    body.setEnabled(false);
    // Move to initial position.
    body.set(shape, MASS);
    body.setPosition(position.x + WIDTH / 2, position.y + HEIGHT / 2);

    // Make sure the gameplay didn't mess with any initial properties.
    body.setCanRest(true);
    body.setDamping(0.0f);
    body.setFriction(0.01f);
    body.setGravityEffected(false);
    body.setIsResting(true);
    body.setMoveable(true);
    body.setRestitution(1.5f);
    body.setRotatable(true);
    body.setRotation(0.0f);
    body.setRotDamping(0.0f);
    body.setMaxVelocity(50f, 50f);
    body.setForce(-body.getForce().getX(), -body.getForce().getY());
    if (currentDirection == Direction.WEST) {
      body.setForce(-MOVEMENT_SPEED, 0);
    } else if (currentDirection == Direction.EAST) {
      body.setForce(MOVEMENT_SPEED, 0);
    }
    if (currentDirection == Direction.NORTH) {
      body.setForce(0, -MOVEMENT_SPEED);
    } else if (currentDirection == Direction.SOUTH) {
      body.setForce(0, MOVEMENT_SPEED);
    }
    body.adjustVelocity(new Vector2f(-body.getVelocity().getX(), -body.getVelocity().getY()));
    body.adjustAngularVelocity(-body.getAngularVelocity());
  }
示例#3
0
  /**
   * Step the simulation. Currently anything other than 1/60f as a step leads to unpredictable
   * results - hence the default step fixes us to this step
   *
   * @param dt The amount of time to step
   */
  public void step(float dt) {
    for (int i = 0; i < bodies.size(); ++i) {
      for (int j = 0; j < sources.size(); j++) {
        ((ForceSource) sources.get(j)).apply(bodies.get(i), dt);
      }
    }

    BodyList bodies = getActiveBodies();
    JointList joints = getActiveJoints();

    float invDT = dt > 0.0f ? 1.0f / dt : 0.0f;

    if (restingBodyDetection) {
      for (int i = 0; i < bodies.size(); ++i) {
        Body b = bodies.get(i);
        b.startFrame();
      }
      for (int i = 0; i < joints.size(); ++i) {
        Joint j = joints.get(i);
        j.getBody1().setIsResting(false);
        j.getBody2().setIsResting(false);
      }
    }

    broadPhase(dt);

    for (int i = 0; i < bodies.size(); ++i) {
      Body b = bodies.get(i);

      if (b.getInvMass() == 0.0f) {
        continue;
      }
      if (b.isResting() && restingBodyDetection) {
        continue;
      }

      Vector2f temp = new Vector2f(b.getForce());
      temp.scale(b.getInvMass());
      if (b.getGravityEffected()) {
        temp.add(gravity);
      }
      temp.scale(dt);

      b.adjustVelocity(temp);

      Vector2f damping = new Vector2f(b.getVelocity());
      damping.scale(-b.getDamping() * b.getInvMass());
      b.adjustVelocity(damping);

      b.adjustAngularVelocity(dt * b.getInvI() * b.getTorque());
      b.adjustAngularVelocity(-b.getAngularVelocity() * b.getInvI() * b.getRotDamping());
    }

    for (int i = 0; i < arbiters.size(); i++) {
      Arbiter arb = arbiters.get(i);
      if (!restingBodyDetection || !arb.hasRestingPair()) {
        arb.preStep(invDT, dt, damping);
      }
    }

    for (int i = 0; i < joints.size(); ++i) {
      Joint j = joints.get(i);
      j.preStep(invDT);
    }

    for (int i = 0; i < iterations; ++i) {
      for (int k = 0; k < arbiters.size(); k++) {
        Arbiter arb = arbiters.get(k);
        if (!restingBodyDetection || !arb.hasRestingPair()) {
          arb.applyImpulse();
        } else {
          arb.getBody1().collided(arb.getBody2());
          arb.getBody2().collided(arb.getBody1());
        }
      }

      for (int k = 0; k < joints.size(); ++k) {
        Joint j = joints.get(k);
        j.applyImpulse();
      }
    }

    for (int i = 0; i < bodies.size(); ++i) {
      Body b = bodies.get(i);

      if (b.getInvMass() == 0.0f) {
        continue;
      }
      if (restingBodyDetection) {
        if (b.isResting()) {
          continue;
        }
      }

      b.adjustPosition(b.getVelocity(), dt);
      b.adjustPosition(b.getBiasedVelocity(), dt);

      b.adjustRotation(dt * b.getAngularVelocity());
      b.adjustRotation(dt * b.getBiasedAngularVelocity());

      b.resetBias();
      b.setForce(0, 0);
      b.setTorque(0);
    }

    if (restingBodyDetection) {
      for (int i = 0; i < bodies.size(); ++i) {
        Body b = bodies.get(i);
        b.endFrame();
      }
    }

    cleanUpArbiters();
  }