protected void updateActivationState(float timeStep) {
    Vector3f tmp = Stack.alloc(Vector3f.class);

    for (int i = 0; i < collisionObjects.size(); i++) {
      CollisionObject colObj = collisionObjects.getQuick(i);
      RigidBody body = RigidBody.upcast(colObj);
      if (body != null) {
        body.updateDeactivation(timeStep);

        if (body.wantsSleeping()) {
          if (body.isStaticOrKinematicObject()) {
            body.setActivationState(CollisionObject.ISLAND_SLEEPING);
          } else {
            if (body.getActivationState() == CollisionObject.ACTIVE_TAG) {
              body.setActivationState(CollisionObject.WANTS_DEACTIVATION);
            }
            if (body.getActivationState() == CollisionObject.ISLAND_SLEEPING) {
              tmp.set(0f, 0f, 0f);
              body.setAngularVelocity(tmp);
              body.setLinearVelocity(tmp);
            }
          }
        } else {
          if (body.getActivationState() != CollisionObject.DISABLE_DEACTIVATION) {
            body.setActivationState(CollisionObject.ACTIVE_TAG);
          }
        }
      }
    }
  }
  protected void integrateTransforms(float timeStep) {
    Vector3f tmp = Stack.alloc(Vector3f.class);
    Transform tmpTrans = Stack.alloc(Transform.class);

    Transform predictedTrans = Stack.alloc(Transform.class);
    for (int i = 0; i < collisionObjects.size(); i++) {
      CollisionObject colObj = collisionObjects.getQuick(i);
      RigidBody body = RigidBody.upcast(colObj);
      if (body != null) {
        body.setHitFraction(1f);

        if (body.isActive() && (!body.isStaticOrKinematicObject())) {
          body.predictIntegratedTransform(timeStep, predictedTrans);

          tmp.sub(predictedTrans.origin, body.getWorldTransform(tmpTrans).origin);
          float squareMotion = tmp.lengthSquared();

          if (body.getCcdSquareMotionThreshold() != 0f
              && body.getCcdSquareMotionThreshold() < squareMotion) {
            if (body.getCollisionShape().isConvex()) {
              ClosestNotMeConvexResultCallback sweepResults =
                  new ClosestNotMeConvexResultCallback(
                      body,
                      body.getWorldTransform(tmpTrans).origin,
                      predictedTrans.origin,
                      getBroadphase().getOverlappingPairCache(),
                      getDispatcher());
              // ConvexShape convexShape = (ConvexShape)body.getCollisionShape();
              SphereShape tmpSphere =
                  new SphereShape(
                      body
                          .getCcdSweptSphereRadius()); // btConvexShape* convexShape =
                                                       // static_cast<btConvexShape*>(body->getCollisionShape());

              sweepResults.collisionFilterGroup = body.getBroadphaseProxy().collisionFilterGroup;
              sweepResults.collisionFilterMask = body.getBroadphaseProxy().collisionFilterMask;

              convexSweepTest(
                  tmpSphere, body.getWorldTransform(tmpTrans), predictedTrans, sweepResults);
              // JAVA NOTE: added closestHitFraction test to prevent objects being stuck
              if (sweepResults.hasHit() && (sweepResults.closestHitFraction > 0.0001f)) {
                body.setHitFraction(sweepResults.closestHitFraction);
                body.predictIntegratedTransform(timeStep * body.getHitFraction(), predictedTrans);
                body.setHitFraction(0f);
                // System.out.printf("clamped integration to hit fraction = %f\n",
                // sweepResults.closestHitFraction);
              }
            }
          }

          body.proceedToTransform(predictedTrans);
        }
      }
    }
  }
 @Override
 public void setGravity(Vector3f gravity) {
   this.gravity.set(gravity);
   for (int i = 0; i < collisionObjects.size(); i++) {
     CollisionObject colObj = collisionObjects.getQuick(i);
     RigidBody body = RigidBody.upcast(colObj);
     if (body != null) {
       body.setGravity(gravity);
     }
   }
 }
  /** Apply gravity, call this once per timestep. */
  public void applyGravity() {
    // todo: iterate over awake simulation islands!
    for (int i = 0; i < collisionObjects.size(); i++) {
      CollisionObject colObj = collisionObjects.getQuick(i);

      RigidBody body = RigidBody.upcast(colObj);
      if (body != null && body.isActive()) {
        body.applyGravity();
      }
    }
  }
  @Override
  public void clearForces() {
    // todo: iterate over awake simulation islands!
    for (int i = 0; i < collisionObjects.size(); i++) {
      CollisionObject colObj = collisionObjects.getQuick(i);

      RigidBody body = RigidBody.upcast(colObj);
      if (body != null) {
        body.clearForces();
      }
    }
  }
 protected void saveKinematicState(float timeStep) {
   for (int i = 0; i < collisionObjects.size(); i++) {
     CollisionObject colObj = collisionObjects.getQuick(i);
     RigidBody body = RigidBody.upcast(colObj);
     if (body != null) {
       // Transform predictedTrans = new Transform();
       if (body.getActivationState() != CollisionObject.ISLAND_SLEEPING) {
         if (body.isKinematicObject()) {
           // to calculate velocities next frame
           body.saveKinematicState(timeStep);
         }
       }
     }
   }
 }
  protected void predictUnconstraintMotion(float timeStep) {
    Transform tmpTrans = Stack.alloc(Transform.class);

    for (int i = 0; i < collisionObjects.size(); i++) {
      CollisionObject colObj = collisionObjects.getQuick(i);
      RigidBody body = RigidBody.upcast(colObj);
      if (body != null) {
        if (!body.isStaticOrKinematicObject()) {
          if (body.isActive()) {
            body.integrateVelocities(timeStep);
            // damping
            body.applyDamping(timeStep);

            body.predictIntegratedTransform(
                timeStep, body.getInterpolationWorldTransform(tmpTrans));
          }
        }
      }
    }
  }
  protected void synchronizeMotionStates() {
    Transform interpolatedTransform = Stack.alloc(Transform.class);

    Transform tmpTrans = Stack.alloc(Transform.class);
    Vector3f tmpLinVel = Stack.alloc(Vector3f.class);
    Vector3f tmpAngVel = Stack.alloc(Vector3f.class);

    // todo: iterate over awake simulation islands!
    for (int i = 0; i < collisionObjects.size(); i++) {
      CollisionObject colObj = collisionObjects.getQuick(i);

      RigidBody body = RigidBody.upcast(colObj);
      if (body != null && body.getMotionState() != null && !body.isStaticOrKinematicObject()) {
        // we need to call the update at least once, even for sleeping objects
        // otherwise the 'graphics' transform never updates properly
        // so todo: add 'dirty' flag
        // if (body->getActivationState() != ISLAND_SLEEPING)
        {
          TransformUtil.integrateTransform(
              body.getInterpolationWorldTransform(tmpTrans),
              body.getInterpolationLinearVelocity(tmpLinVel),
              body.getInterpolationAngularVelocity(tmpAngVel),
              localTime * body.getHitFraction(),
              interpolatedTransform);
          body.getMotionState().setWorldTransform(interpolatedTransform);
        }
      }
    }

    if (getDebugDrawer() != null
        && (getDebugDrawer().getDebugMode() & DebugDrawModes.DRAW_WIREFRAME) != 0) {
      for (int i = 0; i < vehicles.size(); i++) {
        for (int v = 0; v < vehicles.getQuick(i).getNumWheels(); v++) {
          // synchronize the wheels with the (interpolated) chassis worldtransform
          vehicles.getQuick(i).updateWheelTransform(v, true);
        }
      }
    }
  }