AEyeXActorBase* AEyeXPlayerController::FindByBoxedLineTrace(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint, const FCollisionObjectQueryParams& ObjectParams, const FCollisionQueryParams& TraceParams) { UWorld* World = GetWorld(); if (!World) return nullptr; // Set up a box around the gaze point FVector2D Corners[4]; GetBoxCorners(GazePoint, BoxSize * GetApproximatePixelsPerMillimeter(), Corners); // First check center point AEyeXActorBase* EyeXActor = nullptr; FVector Start, End; FEyeXUtils::GetStartAndEndOfLineTrace(View, MaxDistance, GazePoint, /*out*/ Start, /*out*/ End); if (World->LineTraceSingleByObjectType(OutHit, Start, End, ObjectParams, TraceParams)) { EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor()); } else { // If center point missed we perform traces in a box around the gaze point // and choose the closest EyeXActor hit by the traces TArray<AEyeXActorBase*> EyeXActors; for (int i = 0; i < 4; ++i) { FVector BoxStart, BoxEnd; FEyeXUtils::GetStartAndEndOfLineTrace(View, MaxDistance, Corners[i], /*out*/ BoxStart, /*out*/ BoxEnd); if (World->LineTraceSingleByObjectType(OutHit, BoxStart, BoxEnd, ObjectParams, TraceParams)) { AEyeXActorBase* Actor = Cast<AEyeXActorBase>(OutHit.GetActor()); if (!Actor) continue; EyeXActors.Add(Actor); } VisualizeHitTestPoint(bVisualizeDetection, World, BoxStart); } if (EyeXActors.Num() > 0) { FEyeXUtils::ActorDistanceComparer Comparer(PlayerCameraManager); EyeXActors.Sort(Comparer); EyeXActor = EyeXActors[0]; } } VisualizeHit(bVisualizeDetection, World, OutHit); VisualizeGazePoint(bVisualizeDetection, World, Start); return EyeXActor; }
AEyeXActorBase* AEyeXPlayerController::FindByFrustumIntersection(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint, const FCollisionObjectQueryParams& ObjectParams, const FCollisionQueryParams& TraceParams) { UWorld* World = GetWorld(); if (!World) return nullptr; FVector2D Corners[4]; GetBoxCorners(GazePoint, BoxSize * GetApproximatePixelsPerMillimeter(), Corners); // First do a ray cast from the gaze point to determine if something is blocking. // If we happen to find an AEyeXActorBase, we're done FVector Start, End; FEyeXUtils::GetStartAndEndOfLineTrace(View, MaxDistance, GazePoint, /*out*/ Start, /*out*/ End); AEyeXActorBase* EyeXActor = nullptr; if (World->LineTraceSingleByObjectType(OutHit, Start, End, ObjectParams, TraceParams)) { EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor()); } else { // Calculate frustum using the SceneView FConvexVolume Frustum; FEyeXMathHelpers::CalculateFrustum(Corners, View, Frustum); // Check frustum intersection with EyeX Actors TArray<AEyeXActorBase*> EyeXActors; GetEyeXActorsSortedByDistance(EyeXActors); for (AEyeXActorBase* Actor : EyeXActors) { if (FEyeXMathHelpers::IntersectsFrustum(OutHit, Actor, Frustum)) { EyeXActor = Actor; break; } } } VisualizeHit(bVisualizeDetection, World, OutHit); VisualizeGazePoint(bVisualizeDetection, World, Start); return EyeXActor; }
AEyeXActorBase* AEyeXPlayerController::FindByLineTrace(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint, const FCollisionObjectQueryParams& ObjectParams, const FCollisionQueryParams& TraceParams) { UWorld* World = GetWorld(); if (!World) return nullptr; AEyeXActorBase* EyeXActor = nullptr; FVector Start, End; FEyeXUtils::GetStartAndEndOfLineTrace(View, MaxDistance, GazePoint, /*out*/ Start, /*out*/ End); if (World->LineTraceSingleByObjectType(OutHit, Start, End, ObjectParams, TraceParams)) { EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor()); } VisualizeHit(bVisualizeDetection, World, OutHit); VisualizeGazePoint(bVisualizeDetection, World, Start); return EyeXActor; }