private void processInteraction() {
    NUI_INTERACTION_FRAME interactionFrame = new NUI_INTERACTION_FRAME();
    HRESULT hr = interactionStream.GetNextFrame(new DWORD(0), interactionFrame);

    if (FAILED(hr)) {

      // this happens when we did not process the data in the 1/30 of second required by the sdk
      // because we are in java we can sometimes run slow enough to hit this boundary
      // we can safely ignore this and as our code gets faster it will happen less
      if (hr.intValue() == KinectLibrary.E_NUI_FRAME_NO_DATA) {
        return;
      }

      checkRC(hr);
    }

    // get a list of all skeletons and hands with information
    List<Integer> ids = new ArrayList<>();
    List<NUI_HAND_TYPE> types = new ArrayList<>();

    for (NUI_USER_INFO info : interactionFrame.UserInfos) {

      if (info.HandPointerInfos[0].State.intValue() != 0) {

        ids.add(info.SkeletonTrackingId.intValue());
        types.add(info.HandPointerInfos[0].HandType.value);

        gestureTracker.update(
            device,
            interactionFrame.TimeStamp.getValue(),
            info.HandPointerInfos[0].RawX,
            info.HandPointerInfos[0].RawY,
            info.HandPointerInfos[0].RawZ,
            info.SkeletonTrackingId.intValue(),
            info.HandPointerInfos[0].HandType.value);
      }

      if (info.HandPointerInfos[1].State.intValue() != 0) {

        ids.add(info.SkeletonTrackingId.intValue());
        types.add(info.HandPointerInfos[1].HandType.value);

        gestureTracker.update(
            device,
            interactionFrame.TimeStamp.getValue(),
            info.HandPointerInfos[1].RawX,
            info.HandPointerInfos[1].RawY,
            info.HandPointerInfos[1].RawZ,
            info.SkeletonTrackingId.intValue(),
            info.HandPointerInfos[1].HandType.value);
      }
    }

    gestureTracker.findDestroyed(ids, types);
  }
 @Override
 public void clearAllHands() {
   gestureTracker.clearAllHands();
 }