From 5a401e958d19f486f5a06dd5147b0fc6e3a0e69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=BChlem?= <kuehlem@vr.rwth-aachen.de> Date: Tue, 8 Apr 2025 17:09:45 +0200 Subject: [PATCH] Experimenting --- .../Private/GazeTracking/SFGazeTracker.cpp | 43 +++++++++++++++++++ .../Public/GazeTracking/SFGazeTracker.h | 15 ++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp b/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp index e807c34..45eb330 100644 --- a/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp +++ b/Source/StudyFrameworkPlugin/Private/GazeTracking/SFGazeTracker.cpp @@ -368,6 +368,49 @@ float USFGazeTracker::GetPupilDiameter() return 0.0f; } +FProximityGazingResult USFGazeTracker::ComputeProximityGazingForActor(const AActor* Actor) +{ + checkf(Actor, TEXT("[USFGazeTracker::ComputeProximityGazingForActor] Supplied Actor is nullptr")); + const FBox ActorBox = Actor->GetComponentsBoundingBox(); + if (!ActorBox.IsValid) + { + UE_LOG(LogTemp, Error, TEXT("Cannot get bounding box for actor %s"), *Actor->GetName()); + return FProximityGazingResult(); + } + + // Debug + DrawDebugBox(GetWorld(), ActorBox.GetCenter(), ActorBox.GetExtent(), FColor::Red); + + const FGazeRay Gaze = GetWorldGazeDirection(); + const FVector Base = ActorBox.GetCenter(); + const FVector UserOriginToBox = Base - Gaze.Origin; + const float ProjectionLength = FVector::DotProduct(UserOriginToBox, Gaze.Direction); + if (ProjectionLength < 0.0f) + { // Object is behind the user + return FProximityGazingResult(); + } + + // Angle between the User->Box and the Gaze Direction + const float AngleBetweenRays = acosf(FVector::DotProduct(UserOriginToBox.GetSafeNormal(), Gaze.Direction.GetSafeNormal())); + const float GazeRayLength = ProjectionLength / (1 - AngleBetweenRays); + + // Closest point on the ray to the object + const FVector ProjectedPoint = Gaze.Origin + Gaze.Direction * GazeRayLength; + // Closest point on the box to the ray + const FVector ClosestPointToBox = ActorBox.GetClosestPointTo(ProjectedPoint); + // Angle between the two + const FVector ToBoxEdge = ClosestPointToBox - Gaze.Origin; + const FVector ToGazePoint = ProjectedPoint - Gaze.Origin; + const double Angle = FMath::RadiansToDegrees(acosf(FVector::DotProduct(ToBoxEdge.GetSafeNormal(), ToGazePoint.GetSafeNormal()))); + + constexpr double DebugExtend = 2; + const FVector DebugExtendVector = FVector(DebugExtend, DebugExtend, DebugExtend); + DrawDebugBox(GetWorld(), ProjectedPoint, DebugExtendVector, FColor::Green); + DrawDebugBox(GetWorld(), ClosestPointToBox, DebugExtendVector, FColor::Yellow); + + return FProximityGazingResult(ClosestPointToBox, ProjectedPoint, Angle); +} + FGazeRay USFGazeTracker::GetSranipalGazeRayFromData() { FGazeRay GazeRay; diff --git a/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h b/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h index 7b74ae0..681fda4 100644 --- a/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h +++ b/Source/StudyFrameworkPlugin/Public/GazeTracking/SFGazeTracker.h @@ -36,6 +36,15 @@ struct FGazeRay FVector Direction = FVector::ForwardVector; }; +USTRUCT(BlueprintType) +struct FProximityGazingResult +{ + GENERATED_BODY() + UPROPERTY(BlueprintReadOnly) FVector NearestPointOnObject = FVector::ZeroVector; + UPROPERTY(BlueprintReadOnly) FVector NearestPointOnRay = FVector::ZeroVector; + UPROPERTY(BlueprintReadOnly) double Angle = 0; +}; + UCLASS() class STUDYFRAMEWORKPLUGIN_API USFGazeTracker : public UObject { @@ -44,8 +53,7 @@ class STUDYFRAMEWORKPLUGIN_API USFGazeTracker : public UObject public: bool Tick(float DeltaTime); - - + void Init(EGazeTrackerMode Mode, bool IgnoreNonGazeTargetActors, float DataGatheringsPerSecond, EGazeTrackingBackend BackendToUse); //returns pair of Origin and Direction, in world coordinates @@ -84,6 +92,9 @@ public: UPROPERTY(BlueprintReadWrite) bool bDebugRenderRayTraces = false; + UFUNCTION(BlueprintCallable) + FProximityGazingResult ComputeProximityGazingForActor(const AActor* Actor); + private: FGazeRay GetSranipalGazeRayFromData(); -- GitLab