public void setToInterpolateState(
      EntityRef entity, CharacterStateEvent a, CharacterStateEvent b, long time) {
    float t = (float) (time - a.getTime()) / (b.getTime() - a.getTime());
    Vector3f newPos = BaseVector3f.lerp(a.getPosition(), b.getPosition(), t);
    Quat4f newRot = BaseQuat4f.interpolate(a.getRotation(), b.getRotation(), t);
    LocationComponent location = entity.getComponent(LocationComponent.class);
    location.setWorldPosition(newPos);
    location.setWorldRotation(newRot);
    entity.saveComponent(location);

    CharacterMovementComponent movementComponent =
        entity.getComponent(CharacterMovementComponent.class);
    movementComponent.mode = a.getMode();
    movementComponent.setVelocity(a.getVelocity());
    movementComponent.grounded = a.isGrounded();
    if (b.getFootstepDelta() < a.getFootstepDelta()) {
      movementComponent.footstepDelta =
          t * (1 + b.getFootstepDelta() - a.getFootstepDelta()) + a.getFootstepDelta();
      if (movementComponent.footstepDelta > 1) {
        movementComponent.footstepDelta -= 1;
      }
    } else {
      movementComponent.footstepDelta =
          t * (b.getFootstepDelta() - a.getFootstepDelta()) + a.getFootstepDelta();
    }
    entity.saveComponent(movementComponent);

    extrapolateCharacterComponent(entity, b);
    setPhysicsLocation(entity, newPos);
  }
 @SuppressWarnings(value = "SuspiciousNameCombination")
 private void updateRotation(
     CharacterMovementComponent movementComp,
     CharacterStateEvent result,
     CharacterMoveInputEvent input) {
   if (movementComp.faceMovementDirection && result.getVelocity().lengthSquared() > 0.01f) {
     float yaw = (float) Math.atan2(result.getVelocity().x, result.getVelocity().z);
     result.getRotation().set(new Vector3f(0, 1, 0), yaw);
   } else {
     result.getRotation().set(new Quat4f(TeraMath.DEG_TO_RAD * input.getYaw(), 0, 0));
   }
 }
 private void extrapolateLocationComponent(
     EntityRef entity, CharacterStateEvent state, Vector3f newPos) {
   LocationComponent location = entity.getComponent(LocationComponent.class);
   location.setWorldPosition(newPos);
   location.setWorldRotation(state.getRotation());
   entity.saveComponent(location);
 }
 /**
  * Sets the state of the given entity to the state represented by the CharacterStateEvent. The
  * state of the entity is determined by its LocationComponent (location and orientation of physics
  * body), CharacterMovementComponent (velocity and various movement state variables) and
  * CharacterComponent for pitch and yaw (used for the camera).
  *
  * @param entity
  * @param state
  */
 public void setToState(EntityRef entity, CharacterStateEvent state) {
   LocationComponent location = entity.getComponent(LocationComponent.class);
   CharacterMovementComponent movementComp = entity.getComponent(CharacterMovementComponent.class);
   CharacterComponent characterComponent = entity.getComponent(CharacterComponent.class);
   if (location == null || movementComp == null || characterComponent == null) {
     return;
   }
   location.setWorldPosition(state.getPosition());
   location.setWorldRotation(state.getRotation());
   entity.saveComponent(location);
   movementComp.mode = state.getMode();
   movementComp.setVelocity(state.getVelocity());
   movementComp.grounded = state.isGrounded();
   movementComp.footstepDelta = state.getFootstepDelta();
   entity.saveComponent(movementComp);
   characterComponent.pitch = state.getPitch();
   characterComponent.yaw = state.getYaw();
   entity.saveComponent(characterComponent);
   setPhysicsLocation(entity, state.getPosition());
 }
  public static void setToExtrapolateState(EntityRef entity, CharacterStateEvent state, long time) {
    float t = (time - state.getTime()) * 0.0001f;
    Vector3f newPos = new Vector3f(state.getVelocity());
    newPos.scale(t);
    newPos.add(state.getPosition());
    LocationComponent location = entity.getComponent(LocationComponent.class);
    location.setWorldPosition(newPos);
    location.setWorldRotation(state.getRotation());
    entity.saveComponent(location);

    CharacterMovementComponent movementComponent =
        entity.getComponent(CharacterMovementComponent.class);
    movementComponent.mode = state.getMode();
    movementComponent.setVelocity(state.getVelocity());
    movementComponent.grounded = state.isGrounded();
    entity.saveComponent(movementComponent);

    CharacterComponent characterComponent = entity.getComponent(CharacterComponent.class);
    characterComponent.pitch = state.pitch;
    characterComponent.yaw = state.yaw;
    entity.saveComponent(characterComponent);
    setPhysicsLocation(entity, newPos);
  }