mirror of
https://github.com/litruv/TobiiEyetracking.git
synced 2026-07-25 03:06:10 +10:00
Added Tobii from 4.23 + updated
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2017- Tobii Technology AB. All rights reserved.
|
||||
*
|
||||
* @author Temaran | Fredrik Lindh | fredrik.lindh@tobii.com | https://github.com/Temaran
|
||||
******************************************************************************/
|
||||
|
||||
#include "TobiiAimAtGazeComponent.h"
|
||||
#include "TobiiInteractionsBlueprintLibrary.h"
|
||||
#include "TobiiInteractionsInternalTypes.h"
|
||||
#include "TobiiGTOMBlueprintLibrary.h"
|
||||
|
||||
#include "DrawDebugHelpers.h"
|
||||
#include "Engine/World.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "HAL/IConsoleManager.h"
|
||||
|
||||
static TAutoConsoleVariable<int32> CVarAimAtGazeEnabled(TEXT("tobii.interaction.AimAtGazeEnabled"), 1, TEXT("Aim@gaze will rotate the view to align with the gaze point when the user triggers it, usually by entering ADS (Aim Down Sights). 0 - Aim@gaze is off. 1 - Aim@gaze is on."));
|
||||
static TAutoConsoleVariable<float> CVarAimAtGazeDoneThreshold(TEXT("tobii.interaction.AimAtGazeDoneThreshold"), 0.0001, TEXT("If the dot product between the current and target direction quats is smaller than this, we are done rotating."));
|
||||
|
||||
static TAutoConsoleVariable<int32> CVarAimAtGazeDebug(TEXT("tobii.debug.AimAtGaze"), 1, TEXT("0 - Will not visualize aim@gaze debug data. 1 - Will visualize aim@gaze debug data."));
|
||||
|
||||
UTobiiAimAtGazeComponent::UTobiiAimAtGazeComponent()
|
||||
: bAllowRetarget(false)
|
||||
, AimSpeed(0.2f)
|
||||
|
||||
, CurrentFocusComponent(nullptr)
|
||||
, CurrentAimTarget(0.0f, 0.0f, 0.0f)
|
||||
, bIsGazeAiming(false)
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
}
|
||||
|
||||
bool UTobiiAimAtGazeComponent::AimAtGazeAvailable()
|
||||
{
|
||||
return UTobiiInteractionsBlueprintLibrary::IsAimAtGazeEnabled();
|
||||
}
|
||||
|
||||
void UTobiiAimAtGazeComponent::AimAtGaze()
|
||||
{
|
||||
if (!AimAtGazeAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentFocusComponent.Reset();
|
||||
|
||||
FTobiiGazeFocusData FocusData;
|
||||
UTobiiGTOMBlueprintLibrary::GetFilteredGazeFocusData(FocusLayerFilters, bIsWhiteList, true, false, FocusData);
|
||||
if (FocusData.FocusedActor.IsValid())
|
||||
{
|
||||
CurrentFocusComponent = FocusData.FocusedPrimitiveComponent;
|
||||
CurrentAimTarget = FocusData.LastVisibleWorldLocation;
|
||||
bIsGazeAiming = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const FHitResult& GazeHitData = UTobiiGTOMBlueprintLibrary::GetNaiveGazeHit();
|
||||
CurrentAimTarget = GazeHitData.Location;
|
||||
bIsGazeAiming = true;
|
||||
}
|
||||
}
|
||||
|
||||
void UTobiiAimAtGazeComponent::ContinuousAimAtGaze()
|
||||
{
|
||||
if (!AimAtGazeAvailable())
|
||||
{
|
||||
CurrentFocusComponent = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bAllowRetarget)
|
||||
{
|
||||
FTobiiGazeFocusData FocusData;
|
||||
UTobiiGTOMBlueprintLibrary::GetFilteredGazeFocusData(FocusLayerFilters, bIsWhiteList, true, false, FocusData);
|
||||
if (FocusData.FocusedPrimitiveComponent.IsValid())
|
||||
{
|
||||
CurrentFocusComponent = FocusData.FocusedPrimitiveComponent;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrentFocusComponent.IsValid())
|
||||
{
|
||||
FVector TargetFocusPosition;
|
||||
UTobiiGTOMBlueprintLibrary::GetPrimitiveComponentFocusLocation(CurrentFocusComponent.Get(), TargetFocusPosition);
|
||||
|
||||
CurrentAimTarget = TargetFocusPosition;
|
||||
bIsGazeAiming = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentFocusComponent.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void UTobiiAimAtGazeComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
static const auto DrawDebugCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("tobii.debug"));
|
||||
if (CurrentFocusComponent != nullptr && DrawDebugCVar->GetInt() && CVarAimAtGazeDebug.GetValueOnGameThread())
|
||||
{
|
||||
DrawDebugBox(GetWorld(), CurrentAimTarget, FVector(50.0f), FColor::Cyan, false, 0.0f);
|
||||
}
|
||||
|
||||
APlayerController* PlayerController = nullptr;
|
||||
APawn* OwnerPawn = Cast<APawn>(GetOwner());
|
||||
|
||||
// We make it possible to attach AimAtGaze component to either Pawn or PlayerController
|
||||
if (OwnerPawn != nullptr)
|
||||
{
|
||||
PlayerController = Cast<APlayerController>(OwnerPawn->GetController());
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerController = Cast<APlayerController>(GetOwner());
|
||||
}
|
||||
|
||||
if (PlayerController != nullptr)
|
||||
{
|
||||
if (AimAtGazeAvailable() && bIsGazeAiming && PlayerController->PlayerCameraManager != nullptr)
|
||||
{
|
||||
FVector CameraLocation = PlayerController->PlayerCameraManager->GetCameraLocation();
|
||||
FVector AimTargetDirection = CurrentAimTarget - CameraLocation;
|
||||
|
||||
FQuat TargetQuat = AimTargetDirection.ToOrientationQuat();
|
||||
FQuat CurrentControlQuat = FQuat(PlayerController->GetControlRotation());
|
||||
|
||||
CurrentControlQuat = FQuat::Slerp(CurrentControlQuat, TargetQuat, AimSpeed);
|
||||
float DotDistance = (CurrentControlQuat | TargetQuat);
|
||||
|
||||
if ((1.0f - DotDistance) < CVarAimAtGazeDoneThreshold.GetValueOnGameThread())
|
||||
{
|
||||
bIsGazeAiming = false;
|
||||
CurrentControlQuat = TargetQuat;
|
||||
}
|
||||
|
||||
PlayerController->SetControlRotation(CurrentControlQuat.Rotator());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2017- Tobii Technology AB. All rights reserved.
|
||||
*
|
||||
* @author Temaran | Fredrik Lindh | fredrik.lindh@tobii.com | https://github.com/Temaran
|
||||
******************************************************************************/
|
||||
|
||||
#include "TobiiFireAtGazeComponent.h"
|
||||
#include "TobiiInteractionsBlueprintLibrary.h"
|
||||
#include "TobiiGTOMBlueprintLibrary.h"
|
||||
#include "../TobiiInteractionsInternalTypes.h"
|
||||
|
||||
#include "Engine/Engine.h"
|
||||
#include "IEyeTracker.h"
|
||||
#include "Camera/CameraComponent.h"
|
||||
#include "Engine/World.h"
|
||||
#include "HAL/IConsoleManager.h"
|
||||
|
||||
static TAutoConsoleVariable<int32> CVarFireAtGazeEnabled(TEXT("tobii.interaction.FireAtGazeEnabled"), 1, TEXT("Fire at gaze lets you fire where you look when not in ADS (Aim Down Sights) mode. 0 - Fire at gaze is disabled. 1 - Fire at gaze is enabled."));
|
||||
|
||||
UTobiiFireAtGazeComponent::UTobiiFireAtGazeComponent()
|
||||
: CameraComponent(nullptr)
|
||||
|
||||
, FireAtGazeTargetActor(nullptr)
|
||||
, FireAtGazeTargetComponent(nullptr)
|
||||
, FireAtGazeTargetLocation(0.0f, 0.0f, 0.0f)
|
||||
|
||||
, MaxDistance(10000.0f)
|
||||
, NoTargetBehavior(ETobiiFireAtGazeNoTargetBehavior::PointGunToGaze)
|
||||
, TraceChannel(ECC_Visibility)
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
}
|
||||
|
||||
bool UTobiiFireAtGazeComponent::FireAtGazeAvailable()
|
||||
{
|
||||
return CameraComponent != nullptr
|
||||
&& UTobiiInteractionsBlueprintLibrary::IsFireAtGazeEnabled();
|
||||
}
|
||||
|
||||
bool UTobiiFireAtGazeComponent::WantsCrosshair()
|
||||
{
|
||||
if (!FireAtGazeAvailable())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (NoTargetBehavior)
|
||||
{
|
||||
case ETobiiFireAtGazeNoTargetBehavior::PointGunForward:
|
||||
return !FireAtGazeTargetActor.IsValid();
|
||||
case ETobiiFireAtGazeNoTargetBehavior::PointGunToGaze:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void UTobiiFireAtGazeComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
if (!FireAtGazeAvailable() || GEngine == nullptr || !GEngine->EyeTrackingDevice.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FTobiiGazeFocusData FocusData;
|
||||
UTobiiGTOMBlueprintLibrary::GetFilteredGazeFocusData(FocusLayerFilters, bIsWhiteList, true, false, FocusData);
|
||||
if (FocusData.FocusedPrimitiveComponent.IsValid())
|
||||
{
|
||||
FireAtGazeTargetActor = FocusData.FocusedActor;
|
||||
FireAtGazeTargetComponent = FocusData.FocusedPrimitiveComponent;
|
||||
FireAtGazeTargetLocation = FocusData.LastVisibleWorldLocation;
|
||||
}
|
||||
else
|
||||
{
|
||||
FVector GazeRayOrigin, GazeRayDirection;
|
||||
switch (NoTargetBehavior)
|
||||
{
|
||||
case ETobiiFireAtGazeNoTargetBehavior::PointGunForward:
|
||||
{
|
||||
GazeRayOrigin = CameraComponent->GetComponentLocation();
|
||||
GazeRayDirection = CameraComponent->GetForwardVector();
|
||||
break;
|
||||
}
|
||||
|
||||
case ETobiiFireAtGazeNoTargetBehavior::PointGunToGaze:
|
||||
default:
|
||||
{
|
||||
FEyeTrackerGazeData CombinedGazeData;
|
||||
GEngine->EyeTrackingDevice->GetEyeTrackerGazeData(CombinedGazeData);
|
||||
GazeRayOrigin = CombinedGazeData.GazeOrigin;
|
||||
GazeRayDirection = CombinedGazeData.GazeDirection;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FHitResult HitResult;
|
||||
UWorld* World = GetWorld();
|
||||
if (World != nullptr && World->LineTraceSingleByChannel(HitResult, GazeRayOrigin, GazeRayOrigin + GazeRayDirection * MaxDistance, TraceChannel)
|
||||
&& UTobiiGTOMBlueprintLibrary::IsPrimitiveComponentGazeFocusable(HitResult.GetComponent()))
|
||||
{
|
||||
FireAtGazeTargetActor = HitResult.GetActor();
|
||||
FireAtGazeTargetComponent = HitResult.GetComponent();
|
||||
FireAtGazeTargetLocation = HitResult.Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
FireAtGazeTargetActor = nullptr;
|
||||
FireAtGazeTargetComponent = nullptr;
|
||||
FireAtGazeTargetLocation = GazeRayOrigin + GazeRayDirection * MaxDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user