bool ULeapMotionFunctionLibrary::IsConnected() { FLeapMotionDevice* LeapDevice = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (LeapDevice) { return LeapDevice->IsConnected(); } return false; }
void ALeapMotionHandActor::Update(float DeltaSeconds) { FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { Device->GetPinchStrength(HandId, PinchStrength); Device->GetGrabStrength(HandId, GrabStrength); } UpdateBones(DeltaSeconds); OnHandUpdated.Broadcast(HandId, DeltaSeconds); }
void ALeapMotionHandActor::UpdateBones(float DeltaSeconds) { if (BoneActors.Num() == 0) { return; } float CombinedScale = GetCombinedScale(); FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { int BoneArrayIndex = 0; for (ELeapBone LeapBone = bShowArm ? ELeapBone::Forearm : ELeapBone::Palm; LeapBone <= ELeapBone::Finger4Tip; ((int8&)LeapBone)++) { FVector TargetPosition; FRotator TargetOrientation; bool Success = Device->GetBonePostionAndOrientation(HandId, LeapBone, TargetPosition, TargetOrientation); if (Success) { // Offset target position & rotation by the SpawnReference actor's transform FQuat RefQuat = GetRootComponent()->GetComponentRotation().Quaternion(); TargetPosition = RefQuat * TargetPosition * CombinedScale + GetRootComponent()->GetComponentLocation(); TargetOrientation = (RefQuat * TargetOrientation.Quaternion()).Rotator(); // Get current position & rotation ALeapMotionBoneActor* BoneActor = BoneActors[BoneArrayIndex++]; UPrimitiveComponent* PrimitiveComponent = Cast<UPrimitiveComponent>(BoneActor->GetRootComponent()); if (PrimitiveComponent && PrimitiveComponent->IsSimulatingPhysics()) { FVector CurrentPositon = PrimitiveComponent->GetComponentLocation(); FRotator CurrentRotation = PrimitiveComponent->GetComponentRotation(); // Compute linear velocity FVector LinearVelocity = (TargetPosition - CurrentPositon) / DeltaSeconds; // Compute angular velocity FVector Axis; float Angle; ConvertDeltaRotationsToAxisAngle(CurrentRotation, TargetOrientation, Axis, Angle); if (Angle > PI) { Angle -= 2 * PI; } FVector AngularVelcity = Axis * (Angle / DeltaSeconds); // Apply velocities PrimitiveComponent->SetPhysicsLinearVelocity(LinearVelocity); PrimitiveComponent->SetAllPhysicsAngularVelocity(AngularVelcity * 180.0f / PI); } } } } }
// Called when the game starts void ULeapMotionImageComponent::InitializeComponent() { Super::InitializeComponent(); // ... DynamicPassthroughMaterial = UKismetMaterialLibrary::CreateDynamicMaterialInstance(this, PassthroughMaterial); DisplaySurfaceComponent->SetMaterial(0, DynamicPassthroughMaterial); FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { Device->SetImagePolicy(true); } }
void ALeapMotionHandActor::Init(int32 HandIdParam, const TSubclassOf<class ALeapMotionBoneActor>& BoneBlueprint) { FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { Leap::Hand Hand = Device->Frame().hand(HandIdParam); HandId = HandIdParam; bool IsLeft; Device->GetIsHandLeft(HandId, IsLeft); HandSide = IsLeft ? ELeapSide::Left : ELeapSide::Right; } CreateBones(BoneBlueprint); OnHandAdded.Broadcast(HandId); }
void ALeapMotionHandActor::CreateBones(const TSubclassOf<class ALeapMotionBoneActor>& BoneBlueprint) { FActorSpawnParameters SpawnParams; SpawnParams.Owner = GetOwner(); SpawnParams.Instigator = GetInstigator(); float CombinedScale = GetCombinedScale(); FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { for (ELeapBone LeapBone = bShowArm ? ELeapBone::Forearm : ELeapBone::Palm; LeapBone <= ELeapBone::Finger4Tip; ((int8&)LeapBone)++) { FVector Position; FRotator Orientation; float Width; float Length; bool Success = Device->GetBonePostionAndOrientation(HandId, LeapBone, Position, Orientation); Success &= Device->GetBoneWidthAndLength(HandId, LeapBone, Width, Length); if (Success) { FQuat RefQuat = GetRootComponent()->GetComponentRotation().Quaternion(); Position = RefQuat * Position * CombinedScale + GetRootComponent()->GetComponentLocation(); Orientation = (RefQuat * Orientation.Quaternion()).Rotator(); ALeapMotionBoneActor* BoneActor = GWorld->SpawnActor<ALeapMotionBoneActor>(BoneBlueprint ? BoneBlueprint : ALeapMotionBoneActor::StaticClass(), Position, Orientation, SpawnParams); if (BoneActor) { BoneActors.Add(BoneActor); # if WITH_EDITOR BoneActor->SetActorLabel(*FString::Printf(TEXT("LeapBone:%s"), ANSI_TO_TCHAR(LEAP_GET_BONE_NAME(LeapBone)))); # endif BoneActor->AttachRootComponentToActor(this, NAME_None, EAttachLocation::KeepWorldPosition, true); BoneActor->Init(LeapBone, CombinedScale, Width, Length, bShowCollider, bShowMesh); } } } } }
void ULeapMotionImageComponent::UpdateImageTexture() { FLeapMotionDevice* Device = FLeapMotionControllerPlugin::GetLeapDeviceSafe(); if (Device && Device->IsConnected()) { Device->SetReferenceFrameOncePerTick(); } if (Device && Device->IsConnected() && Device->Frame().images().count() > 1) { Leap::ImageList ImageList = Device->Frame().images(); for (int eye = 0; eye < 2; eye++) { Leap::Image Image = ImageList[eye]; bool isRGB = Image.format() != Leap::Image::INFRARED; UTexture2D*& Texture = eye ? ImagePassthroughRight : ImagePassthroughLeft; UTexture2D*& Distortion = eye ? DistortionTextureRight : DistortionTextureLeft; // Recreate the image & distortion textures. if (!Texture || Image.width() != Texture->PlatformData->SizeX || Image.height() != Texture->PlatformData->SizeY) { EPixelFormat PixelFormat = !isRGB ? PF_G8 : PF_R8G8B8A8; Texture = UTexture2D::CreateTransient(Image.width(), Image.height(), PixelFormat); Texture->SRGB = 0; Texture->UpdateResource(); Distortion = BuildDistortionTextures(Image); if (isRGB) { DynamicPassthroughMaterial->SetTextureParameterValue(eye ? TEXT("BaseTextureRGB_Right") : TEXT("BaseTextureRGB"), Texture); DynamicPassthroughMaterial->SetScalarParameterValue(TEXT("ImageFormat"), 1.0); } else { DynamicPassthroughMaterial->SetTextureParameterValue(eye ? TEXT("BaseTextureIR_Right") : TEXT("BaseTextureIR"), Texture); DynamicPassthroughMaterial->SetScalarParameterValue(TEXT("ImageFormat"), -1.0); } DynamicPassthroughMaterial->SetTextureParameterValue(eye ? TEXT("DistortionTextureRight") : TEXT("DistortionTexture"), Distortion); if (GEngine && GEngine->GameViewport && GEngine->GameViewport->Viewport) { FIntPoint Resolution = GEngine->GameViewport->Viewport->GetSizeXY(); FLinearColor ScreenRes = FLinearColor(Resolution.X, Resolution.Y, 0.f, 0.f); DynamicPassthroughMaterial->SetVectorParameterValue(TEXT("ScreenResolution"), ScreenRes); } AttachDisplaySurface(); } // Extract the image { UTexture2D*& Texture = eye ? ImagePassthroughRight : ImagePassthroughLeft; const uint8* LeapData = Image.data(); const int LeapDataSize = Image.width() * Image.height() * Image.bytesPerPixel(); //Check for dragonfly if (!isRGB) { uint8* Dest = (uint8*)Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(Dest, LeapData, LeapDataSize); } else { uint32* Dest = (uint32*)Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE); FMemory::Memcpy(Dest, LeapData, LeapDataSize); } Texture->PlatformData->Mips[0].BulkData.Unlock(); Texture->UpdateResource(); } // Hack: need to update distortion texture every frame to handle device flipping. UpdateDistortionTextures(Image, Distortion); } const bool bUsingHmd = GEngine->HMDDevice.IsValid() && GEngine->HMDDevice->IsHeadTrackingAllowed(); DynamicPassthroughMaterial->SetScalarParameterValue("HorizontalTanHalfFOV", bUsingHmd ? 1.4f : 1.0f); } else { // We can't find two images, that might be due to device being detached & maybe exchanged later -- trigger reset. ImagePassthroughLeft = nullptr; ImagePassthroughRight = nullptr; DistortionTextureLeft = nullptr; DistortionTextureRight = nullptr; } }