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