fdata get_finger_positions() { Leap::Frame frame = control.frame(); Leap::FingerList fingers = frame.fingers(); Leap::ToolList tools = frame.tools(); Leap::HandList hands = frame.hands(); //std::vector<std::pair<cl_float4, int>> positions; fdata hand_data; int p = 0; for(int i=0; i<40; i++) { hand_data.fingers[i] = 0.0f; } ///will explode if more than 2 for(int i=0; i<hands.count(); i++) { const Leap::Hand hand = hands[i]; Leap::FingerList h_fingers = hand.fingers(); float grab_strength = hand.grabStrength(); hand_data.grab_confidence[i] = grab_strength; for(int j=0; j<h_fingers.count(); j++) { const Leap::Finger finger = h_fingers[j]; float mfingerposx = finger.tipPosition().x; float mfingerposy = finger.tipPosition().y; float mfingerposz = finger.tipPosition().z; //cl_float4 ps = {mfingerposx, mfingerposy, mfingerposz, 0.0f}; //cl_float4 ps = {mfingerposx, mfingerposy, mfingerposz, 0.0f}; int id = finger.id(); hand_data.fingers[p++] = mfingerposx; hand_data.fingers[p++] = mfingerposy; hand_data.fingers[p++] = mfingerposz; hand_data.fingers[p++] = 0.0f; //positions.push_back(std::pair<cl_float4, int>(ps, id)); } } return hand_data; }
//Main Event driven tick void ULeapController::InterfaceEventTick(float DeltaTime) { //This is our tick event that is forwarded from the delegate, check validity if (!_private->interfaceDelegate) return; //Pointers Leap::Frame frame = _private->leap.frame(); Leap::Frame pastFrame = _private->leap.frame(1); //-Hands- //Hand Count int handCount = frame.hands().count(); if (_private->pastState.handCount != handCount) { ILeapEventInterface::Execute_HandCountChanged(_private->interfaceDelegate, handCount); //Zero our input mapping orientations (akin to letting go of a joystick) if (handCount == 0) { EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, 0, 0, 0); } } //Cycle through each hand for (int i = 0; i < handCount; i++) { Leap::Hand hand = frame.hands()[i]; LeapHandStateData pastHandState = _private->pastState.stateForId(hand.id()); //we use a custom class to hold reliable state tracking based on id's //Make a ULeapHand if (_private->eventHand == NULL) { _private->eventHand = NewObject<ULeapHand>(this); _private->eventHand->SetFlags(RF_RootSet); } _private->eventHand->setHand(hand); //Emit hand ILeapEventInterface::Execute_LeapHandMoved(_private->interfaceDelegate, _private->eventHand); //Left/Right hand forwarding if (hand.isRight()) { ILeapEventInterface::Execute_LeapRightHandMoved(_private->interfaceDelegate, _private->eventHand); //Input Mapping FRotator palmOrientation = _private->eventHand->PalmOrientation; EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, palmOrientation.Pitch * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, palmOrientation.Yaw * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, palmOrientation.Roll * LEAP_IM_SCALE, 0, 0); } else if (hand.isLeft()) { ILeapEventInterface::Execute_LeapLeftHandMoved(_private->interfaceDelegate, _private->eventHand); //Input Mapping FRotator palmOrientation = _private->eventHand->PalmOrientation; EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, palmOrientation.Pitch * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, palmOrientation.Yaw * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, palmOrientation.Roll * LEAP_IM_SCALE, 0, 0); } //Grabbing float grabStrength = hand.grabStrength(); bool grabbed = handClosed(grabStrength); if (grabbed) ILeapEventInterface::Execute_LeapHandGrabbing(_private->interfaceDelegate, grabStrength, _private->eventHand); if (grabbed && !pastHandState.grabbed) { ILeapEventInterface::Execute_LeapHandGrabbed(_private->interfaceDelegate, grabStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyDownEventForKey(EKeysLeap::LeapLeftGrab, 0, 0); else EmitKeyDownEventForKey(EKeysLeap::LeapRightGrab, 0, 0); }else if (!grabbed && pastHandState.grabbed) { ILeapEventInterface::Execute_LeapHandReleased(_private->interfaceDelegate, grabStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyUpEventForKey(EKeysLeap::LeapLeftGrab, 0, 0); else EmitKeyUpEventForKey(EKeysLeap::LeapRightGrab, 0, 0); } //Pinching float pinchStrength = hand.pinchStrength(); bool pinched = handPinched(pinchStrength); //While grabbing disable pinching detection, this helps to reduce spam as pose confidence plummets if (grabbed) pinched = pastHandState.pinched; else { if (pinched) ILeapEventInterface::Execute_LeapHandPinching(_private->interfaceDelegate, pinchStrength, _private->eventHand); if (pinched && !pastHandState.pinched) { ILeapEventInterface::Execute_LeapHandPinched(_private->interfaceDelegate, pinchStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyDownEventForKey(EKeysLeap::LeapLeftPinch, 0, 0); else EmitKeyDownEventForKey(EKeysLeap::LeapRightPinch, 0, 0); } else if (!pinched && pastHandState.pinched) { ILeapEventInterface::Execute_LeapHandUnpinched(_private->interfaceDelegate, pinchStrength, _private->eventHand); //input mapping if (_private->eventHand->HandType == LeapHandType::HAND_LEFT) EmitKeyUpEventForKey(EKeysLeap::LeapLeftPinch, 0, 0); else EmitKeyUpEventForKey(EKeysLeap::LeapRightPinch, 0, 0); } } //-Fingers- Leap::FingerList fingers = hand.fingers(); //Count int fingerCount = fingers.count(); if ((pastHandState.fingerCount != fingerCount)) ILeapEventInterface::Execute_FingerCountChanged(_private->interfaceDelegate, fingerCount); if (_private->eventFinger == NULL) { _private->eventFinger = NewObject<ULeapFinger>(this); _private->eventFinger->SetFlags(RF_RootSet); } Leap::Finger finger; //Cycle through each finger for (int j = 0; j < fingerCount; j++) { finger = fingers[j]; _private->eventFinger->setFinger(finger); //Finger Moved if (finger.isValid()) ILeapEventInterface::Execute_LeapFingerMoved(_private->interfaceDelegate, _private->eventFinger); } //Do these last so we can easily override debug shapes //Leftmost finger = fingers.leftmost(); _private->eventFinger->setFinger(finger); ILeapEventInterface::Execute_LeapLeftMostFingerMoved(_private->interfaceDelegate, _private->eventFinger); //Rightmost finger = fingers.rightmost(); _private->eventFinger->setFinger(finger); ILeapEventInterface::Execute_LeapRightMostFingerMoved(_private->interfaceDelegate, _private->eventFinger); //Frontmost finger = fingers.frontmost(); _private->eventFinger->setFinger(finger); ILeapEventInterface::Execute_LeapFrontMostFingerMoved(_private->interfaceDelegate, _private->eventFinger); //touch only for front-most finger, most common use case float touchDistance = finger.touchDistance(); if (touchDistance <= 0.f) ILeapEventInterface::Execute_LeapFrontFingerTouch(_private->interfaceDelegate, _private->eventFinger); //Set the state data for next cycle pastHandState.grabbed = grabbed; pastHandState.pinched = pinched; pastHandState.fingerCount = fingerCount; _private->pastState.setStateForId(pastHandState, hand.id()); } _private->pastState.handCount = handCount; //Gestures for (int i = 0; i < frame.gestures().count(); i++) { Leap::Gesture gesture = frame.gestures()[i]; Leap::Gesture::Type type = gesture.type(); switch (type) { case Leap::Gesture::TYPE_CIRCLE: if (_private->eventCircleGesture == NULL){ _private->eventCircleGesture = NewObject<ULeapCircleGesture>(this); _private->eventCircleGesture->SetFlags(RF_RootSet); } _private->eventCircleGesture->setGesture(Leap::CircleGesture(gesture)); ILeapEventInterface::Execute_CircleGestureDetected(_private->interfaceDelegate, _private->eventCircleGesture); _private->eventGesture = _private->eventCircleGesture; break; case Leap::Gesture::TYPE_KEY_TAP: if (_private->eventKeyTapGesture == NULL) { _private->eventKeyTapGesture = NewObject<ULeapKeyTapGesture>(this); _private->eventKeyTapGesture->SetFlags(RF_RootSet); } _private->eventKeyTapGesture->setGesture(Leap::KeyTapGesture(gesture)); ILeapEventInterface::Execute_KeyTapGestureDetected(_private->interfaceDelegate, _private->eventKeyTapGesture); _private->eventGesture = _private->eventKeyTapGesture; break; case Leap::Gesture::TYPE_SCREEN_TAP: if (_private->eventScreenTapGesture == NULL) { _private->eventScreenTapGesture = NewObject<ULeapScreenTapGesture>(this); _private->eventScreenTapGesture->SetFlags(RF_RootSet); } _private->eventScreenTapGesture->setGesture(Leap::ScreenTapGesture(gesture)); ILeapEventInterface::Execute_ScreenTapGestureDetected(_private->interfaceDelegate, _private->eventScreenTapGesture); _private->eventGesture = _private->eventScreenTapGesture; break; case Leap::Gesture::TYPE_SWIPE: if (_private->eventSwipeGesture == NULL) { _private->eventSwipeGesture = NewObject<ULeapSwipeGesture>(this); _private->eventSwipeGesture->SetFlags(RF_RootSet); } _private->eventSwipeGesture->setGesture(Leap::SwipeGesture(gesture)); ILeapEventInterface::Execute_SwipeGestureDetected(_private->interfaceDelegate, _private->eventSwipeGesture); _private->eventGesture = _private->eventSwipeGesture; break; default: break; } //emit gesture if (type != Leap::Gesture::TYPE_INVALID) { ILeapEventInterface::Execute_GestureDetected(_private->interfaceDelegate, _private->eventGesture); } } //Image if (_private->allowImages && _private->imageEventsEnabled) { int imageCount = frame.images().count(); for (int i = 0; i < imageCount; i++) { Leap::Image image = frame.images()[i]; //Loop modification - Only emit 0 and 1, use two different pointers so we can get different images if (i == 0) { if (_private->eventImage1 == NULL) { _private->eventImage1 = NewObject<ULeapImage>(this); _private->eventImage1->SetFlags(RF_RootSet); } _private->eventImage1->setLeapImage(image); ILeapEventInterface::Execute_RawImageReceived(_private->interfaceDelegate, _private->eventImage1->Texture(), _private->eventImage1); } else if (i == 1) { if (_private->eventImage2 == NULL) { _private->eventImage2 = NewObject<ULeapImage>(this); _private->eventImage2->SetFlags(RF_RootSet); } _private->eventImage2->setLeapImage(image); ILeapEventInterface::Execute_RawImageReceived(_private->interfaceDelegate, _private->eventImage2->Texture(), _private->eventImage2); } } } }
//------------------------------------------------------------------------------------- bool DigitalForensicsVisualisation::updateFrame(const Ogre::FrameEvent& evt) { pointLight->setPosition(mCamera->getPosition()); //leap const Frame frame = leapController.frame(); Leap::Hand rightMost = frame.hands().rightmost(); #pragma region hand // // //if (!frame.hands().isEmpty() && !handOrientationFlag) //{ // // palmNode->resetOrientation(); // handOrientationFlag = true; //} //else if (handOrientationFlag && frame.hands().isEmpty() ) //{ // handOrientationFlag = false; //} #pragma endregion hand if (!frame.hands().isEmpty()) { Leap::Hand rightMost = frame.hands().rightmost(); float pitchValue = rightMost.direction().pitch() * RAD_TO_DEG; float rollValue = rightMost.palmNormal().roll() * RAD_TO_DEG; float yawValue = rightMost.direction().yaw() * RAD_TO_DEG; // to detect open and closed hand Ogre::Vector3 indexTip = toVector(rightMost.fingers()[1].tipPosition()); Ogre::Vector3 pinkyTip = toVector(rightMost.fingers()[3].tipPosition()); float angle = std::abs(indexTip.x - pinkyTip.x); angle /= rightMost.fingers()[1].length(); // to normalise if (rightMost.grabStrength() == 1) { if (mCamera->getOrientation().getPitch() + (Ogre::Radian) (rightMost.palmPosition().y - previousPosition.y) / 80 < (Ogre::Radian) 0.17 && mCamera->getOrientation().getPitch() + (Ogre::Radian) (rightMost.palmPosition().y - previousPosition.y) / 80 > (Ogre::Radian) -1.4) mCamera->pitch((Ogre::Radian) (rightMost.palmPosition().y - previousPosition.y) / 80); //mCamera->yaw((Ogre::Radian) (rightMost.palmPosition().x - previousPosition.x) / -80); //mCamera->roll((Ogre::Radian) (rollValue - previousFrameRoll) / 30); } else if (angle > 0.65) { //palmNode->setPosition(toVector(frame.hands().rightmost().palmPosition())); // between 100 and 250 if ((mCamera->getPosition().y + (frame.hands().rightmost().palmPosition().y - previousPosition.y)*2 ) > -290) mCamera->setPosition(mCamera->getPosition() + (toVector(frame.hands().rightmost().palmPosition()) - previousPosition)*2 ); } //else //{ // mCamera->yaw((Ogre::Radian) (yawValue - previousFrameYaw) / -10); //} previousPosition = toVector(frame.hands().rightmost().palmPosition()); #pragma region hand //palmNode->pitch((Ogre::Radian) (pitchValue - previousFramePitch) ); // //palmNode->roll((Ogre::Radian) (rollValue - previousFrameRoll) ); // //palmNode->yaw((Ogre::Radian) (yawValue - previousFrameYaw) ); //previousFramePitch = rightMost.direction().pitch() * RAD_TO_DEG; //previousFrameYaw = rightMost.direction().yaw() * RAD_TO_DEG; //previousFrameRoll = rightMost.palmNormal().roll() * RAD_TO_DEG; // Get fingers //FingerList fingers; //fingers = rightMost.fingers(); //int i = 0; //between 0 and 19 (finger bones) // //for (FingerList::const_iterator fl = fingers.begin(); fl != fingers.end(); ++fl) //{ // // Finger finger; // finger = *fl; // // // /*char* dummy = (char*) malloc(128); // sprintf (dummy, "finger id: %d, length: %f, width: %f\n", finger.id(), finger.length(), finger.width()); // OutputDebugString (dummy); // free(dummy);*/ // // Get finger bones // for (int b = 0; b < 4; ++b) // { // Bone::Type boneType; // boneType = static_cast<Bone::Type>(b); // Bone bone; // bone = finger.bone(boneType); // bonesArr[i++]->setPosition(bone.center().x, bone.center().y, bone.center().z); // } //} // to detect fist /*char* dummy = (char*) malloc(8); sprintf (dummy, "%f\n", rightMost.grabStrength()); OutputDebugString(dummy);*/ // to detect open and closed hand //Ogre::Vector3 indexTip = toVector(rightMost.fingers()[1].tipPosition()); //Ogre::Vector3 pinkyTip = toVector(rightMost.fingers()[3].tipPosition()); //float angle = std::abs(indexTip.x - pinkyTip.x); //angle /= rightMost.fingers()[1].length(); // to normalise // //char* dummy = (char*) malloc(8); //sprintf (dummy, "%f\n", angle); //OutputDebugString(dummy); #pragma endregion hand } return true; }
void FLeapMotionInputDevice::ParseEvents() { //Optimization: If we don't have any delegates, skip if (EventDelegates.Num() == 0) { return; } //Pointers Leap::Frame Frame = ControllerData.LeapController.frame(); Leap::Frame PastFrame = ControllerData.LeapController.frame(1); //Calculate HMD Timewarp if valid if (GEngine->HMDDevice.IsValid() && ControllerData.bTimeWarpEnabled) { LeapHMDSnapshot ThenSnapshot = HMDSamples->HMDSampleClosestToTimestamp(Frame.timestamp()); LeapHMDSnapshot NowSnapShot = HMDSamples->CurrentHMDSample(); LeapHMDSnapshot HistorySnapshot = HMDSamples->LastHMDSample(); //reduce jitter //ControllerData.TimeWarpSnapshot = NowSnapShot.Difference(ThenSnapshot, ControllerData.TimeWarpFactor);// * ControllerData.TimeWarpFactor; FQuat WarpQuat = NowSnapShot.Orientation;//FQuat::Slerp(NowSnapShot.Orientation, HistorySnapshot.Orientation, ControllerData.TimeWarpTween); FQuat ThenTweened = FQuat::Slerp(ThenSnapshot.Orientation, HistorySnapshot.Orientation, ControllerData.TimeWarpTween); ControllerData.TimeWarpSnapshot.Orientation = (WarpQuat.Inverse() * ControllerData.TimeWarpFactor) * ThenTweened; ControllerData.TimeWarpAmountMs = (ControllerData.TimeWarpSnapshot.Timestamp) / 1000.f; } //-Hands- //Hand Count int HandCount = Frame.hands().count(); if (PastState->HandCount != HandCount) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_HandCountChanged(EventDelegate, HandCount); }); //Zero our input mapping orientations (akin to letting go of a joystick) if (HandCount == 0) { EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, 0, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, 0, 0, 0); } } //Cycle through each hand for (int i = 0; i < HandCount; i++) { Leap::Hand Hand = Frame.hands()[i]; LeapHandStateData PastHandState = PastState->StateForId(Hand.id()); //we use a custom class to hold reliable state tracking based on id's //Make a ULeapHand if (PEventHand == nullptr) { PEventHand = NewObject<ULeapHand>(); PEventHand->AddToRoot(); } PEventHand->SetHand(Hand); //Emit hand CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandMoved(EventDelegate, PEventHand); }); //Left/Right hand forwarding if (Hand.isRight()) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapRightHandMoved(EventDelegate, PEventHand); }); //Input Mapping FRotator PalmOrientation = PEventHand->PalmOrientation; EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, PalmOrientation.Pitch * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, PalmOrientation.Yaw * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, PalmOrientation.Roll * LEAP_IM_SCALE, 0, 0); } else if (Hand.isLeft()) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapLeftHandMoved(EventDelegate, PEventHand); }); //Input Mapping FRotator PalmOrientation = PEventHand->PalmOrientation; EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, PalmOrientation.Pitch * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, PalmOrientation.Yaw * LEAP_IM_SCALE, 0, 0); EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, PalmOrientation.Roll * LEAP_IM_SCALE, 0, 0); } //Grabbing float GrabStrength = Hand.grabStrength(); bool Grabbed = HandClosed(GrabStrength); if (Grabbed) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandGrabbing(EventDelegate, GrabStrength, PEventHand); }); } if (Grabbed && !PastHandState.Grabbed) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandGrabbed(EventDelegate, GrabStrength, PEventHand); }); //input mapping if (PEventHand->HandType == LeapHandType::HAND_LEFT) { EmitKeyDownEventForKey(EKeysLeap::LeapLeftGrab, 0, 0); } else { EmitKeyDownEventForKey(EKeysLeap::LeapRightGrab, 0, 0); } } else if (!Grabbed && PastHandState.Grabbed) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandReleased(EventDelegate, GrabStrength, PEventHand); }); //input mapping if (PEventHand->HandType == LeapHandType::HAND_LEFT) { EmitKeyUpEventForKey(EKeysLeap::LeapLeftGrab, 0, 0); } else { EmitKeyUpEventForKey(EKeysLeap::LeapRightGrab, 0, 0); } } //Pinching float PinchStrength = Hand.pinchStrength(); bool Pinched = HandPinched(PinchStrength); //While grabbing disable pinching detection, this helps to reduce spam as pose confidence plummets if (Grabbed) { Pinched = PastHandState.Pinched; } else { if (Pinched) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandPinching(EventDelegate, PinchStrength, PEventHand); }); } if (Pinched && !PastHandState.Pinched) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandPinched(EventDelegate, PinchStrength, PEventHand); }); //input mapping if (PEventHand->HandType == LeapHandType::HAND_LEFT) { EmitKeyDownEventForKey(EKeysLeap::LeapLeftPinch, 0, 0); } else { EmitKeyDownEventForKey(EKeysLeap::LeapRightPinch, 0, 0); } } else if (!Pinched && PastHandState.Pinched) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapHandUnpinched(EventDelegate, PinchStrength, PEventHand); }); //input mapping if (PEventHand->HandType == LeapHandType::HAND_LEFT) { EmitKeyUpEventForKey(EKeysLeap::LeapLeftPinch, 0, 0); } else { EmitKeyUpEventForKey(EKeysLeap::LeapRightPinch, 0, 0); } } } //-Fingers- Leap::FingerList Fingers = Hand.fingers(); //Count int FingerCount = Fingers.count(); if ((PastHandState.FingerCount != FingerCount)) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_FingerCountChanged(EventDelegate, FingerCount); }); } if (PEventFinger == nullptr) { PEventFinger = NewObject<ULeapFinger>(); PEventFinger->AddToRoot(); } Leap::Finger Finger; //Cycle through each finger for (int j = 0; j < FingerCount; j++) { Finger = Fingers[j]; PEventFinger->SetFinger(Finger); //Finger Moved if (Finger.isValid()) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapFingerMoved(EventDelegate, PEventFinger); }); } } //Do these last so we can easily override debug shapes //Leftmost Finger = Fingers.leftmost(); PEventFinger->SetFinger(Finger); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapLeftMostFingerMoved(EventDelegate, PEventFinger); }); //Rightmost Finger = Fingers.rightmost(); PEventFinger->SetFinger(Finger); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapRightMostFingerMoved(EventDelegate, PEventFinger); }); //Frontmost Finger = Fingers.frontmost(); PEventFinger->SetFinger(Finger); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapFrontMostFingerMoved(EventDelegate, PEventFinger); }); //touch only for front-most finger, most common use case float touchDistance = Finger.touchDistance(); if (touchDistance <= 0.f) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_LeapFrontFingerTouch(EventDelegate, PEventFinger); }); } //Set the state data for next cycle PastHandState.Grabbed = Grabbed; PastHandState.Pinched = Pinched; PastHandState.FingerCount = FingerCount; PastState->SetStateForId(PastHandState, Hand.id()); } PastState->HandCount = HandCount; //Gestures for (int i = 0; i < Frame.gestures().count(); i++) { Leap::Gesture Gesture = Frame.gestures()[i]; Leap::Gesture::Type Type = Gesture.type(); switch (Type) { case Leap::Gesture::TYPE_CIRCLE: if (PEventCircleGesture == nullptr) { PEventCircleGesture = NewObject<ULeapCircleGesture>(); PEventCircleGesture->AddToRoot(); } PEventCircleGesture->SetGesture(Leap::CircleGesture(Gesture)); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_CircleGestureDetected(EventDelegate, PEventCircleGesture); }); PEventGesture = PEventCircleGesture; break; case Leap::Gesture::TYPE_KEY_TAP: if (PEventKeyTapGesture == nullptr) { PEventKeyTapGesture = NewObject<ULeapKeyTapGesture>(); PEventKeyTapGesture->AddToRoot(); } PEventKeyTapGesture->SetGesture(Leap::KeyTapGesture(Gesture)); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_KeyTapGestureDetected(EventDelegate, PEventKeyTapGesture); }); PEventGesture = PEventKeyTapGesture; break; case Leap::Gesture::TYPE_SCREEN_TAP: if (PEventScreenTapGesture == nullptr) { PEventScreenTapGesture = NewObject<ULeapScreenTapGesture>(); PEventScreenTapGesture->AddToRoot(); } PEventScreenTapGesture->SetGesture(Leap::ScreenTapGesture(Gesture)); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_ScreenTapGestureDetected(EventDelegate, PEventScreenTapGesture); }); PEventGesture = PEventScreenTapGesture; break; case Leap::Gesture::TYPE_SWIPE: if (PEventSwipeGesture == nullptr) { PEventSwipeGesture = NewObject<ULeapSwipeGesture>(); PEventSwipeGesture->AddToRoot(); } PEventSwipeGesture->SetGesture(Leap::SwipeGesture(Gesture)); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_SwipeGestureDetected(EventDelegate, PEventSwipeGesture); }); PEventGesture = PEventSwipeGesture; break; default: break; } //emit gesture if (Type != Leap::Gesture::TYPE_INVALID) { CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_GestureDetected(EventDelegate, PEventGesture); }); } } //Image if (ControllerData.bAllowImageEvents && ControllerData.bImageEventsEnabled) { int ImageCount = Frame.images().count(); //We only support getting both images if (ImageCount >= 2) { Leap::Image Image1 = Frame.images()[0]; if (PEventImage1 == nullptr) { PEventImage1 = NewObject<ULeapImage>(); PEventImage1->AddToRoot(); } PEventImage1->UseGammaCorrection = ControllerData.bUseGammaCorrection; PEventImage1->SetLeapImage(Image1); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_RawImageReceived(EventDelegate, PEventImage1->Texture(), PEventImage1); }); Leap::Image Image2 = Frame.images()[1]; if (PEventImage2 == nullptr) { PEventImage2 = NewObject<ULeapImage>(); PEventImage2->AddToRoot(); } PEventImage2->UseGammaCorrection = ControllerData.bUseGammaCorrection; PEventImage2->SetLeapImage(Image2); CallFunctionOnDelegates([&](UObject* EventDelegate) { ILeapEventInterface::Execute_RawImageReceived(EventDelegate, PEventImage2->Texture(), PEventImage2); }); } } }