The following code is from the StrategyGame demo:
void UStrategyCameraComponent::ClampCameraLocation( const APlayerController* InPlayerController, FVector& OutCameraLocation )
{
if (bShouldClampCamera)
{
UpdateCameraBounds(InPlayerController);
if (CameraMovementBounds.GetSize() != FVector::ZeroVector)
{
OutCameraLocation = CameraMovementBounds.GetClosestPointTo(OutCameraLocation);
}
}
}
void UStrategyCameraComponent::UpdateCameraBounds( const APlayerController* InPlayerController )
{
ULocalPlayer* const LocalPlayer = Cast<ULocalPlayer>(InPlayerController->Player);
if (LocalPlayer == NULL || LocalPlayer->ViewportClient == NULL)
{
return;
}
FVector2D CurrentViewportSize;
LocalPlayer->ViewportClient->GetViewportSize(CurrentViewportSize);
// calc frustum edge direction, from bottom left corner
if (CameraMovementBounds.GetSize() == FVector::ZeroVector || CurrentViewportSize != CameraMovementViewportSize)
{
// calc frustum edge direction, from bottom left corner
const FVector FrustumRay2DDir = FVector(1,1,0).SafeNormal();
const FVector FrustumRay2DRight = FVector::CrossProduct(FrustumRay2DDir, FVector::UpVector);
const FQuat RotQuat(FrustumRay2DRight, FMath::DegreesToRadians(90.0f - InPlayerController->PlayerCameraManager->GetFOVAngle() * 0.5f));
const FVector FrustumRayDir = RotQuat.RotateVector(FrustumRay2DDir);
// collect 3 world bounds' points and matching frustum rays (bottom left, top left, bottom right)
AStrategyGameState const* const MyGameState = GetWorld()->GetGameState<AStrategyGameState>();
if (MyGameState)
{
FBox const& WorldBounds = MyGameState->WorldBounds;
if (WorldBounds.GetSize() != FVector::ZeroVector)
{
const FVector WorldBoundPoints] = {
FVector(WorldBounds.Min.X, WorldBounds.Min.Y, WorldBounds.Max.Z),
FVector(WorldBounds.Min.X, WorldBounds.Max.Y, WorldBounds.Max.Z),
FVector(WorldBounds.Max.X, WorldBounds.Min.Y, WorldBounds.Max.Z)
};
const FVector FrustumRays] = {
FVector( FrustumRayDir.X, FrustumRayDir.Y, FrustumRayDir.Z),
FVector( FrustumRayDir.X, -FrustumRayDir.Y, FrustumRayDir.Z),
FVector(-FrustumRayDir.X, FrustumRayDir.Y, FrustumRayDir.Z)
};
// get camera plane for intersections
const FPlane CameraPlane = FPlane(InPlayerController->GetFocalLocation(), FVector::UpVector);
// get matching points on camera plane
const FVector CameraPlanePoints[3] = {
FStrategyHelpers::IntersectRayWithPlane(WorldBoundPoints[0], FrustumRays[0], CameraPlane)*MiniMapBoundsLimit,
FStrategyHelpers::IntersectRayWithPlane(WorldBoundPoints[1], FrustumRays[1], CameraPlane)*MiniMapBoundsLimit,
FStrategyHelpers::IntersectRayWithPlane(WorldBoundPoints[2], FrustumRays[2], CameraPlane)*MiniMapBoundsLimit
};
// create new bounds
CameraMovementBounds = FBox(CameraPlanePoints, 3);
CameraMovementViewportSize = CurrentViewportSize;
}
}
}
}
Can anyone explain the purpose of WorldBoundPoints, FrustumRays and CameraPlanePoints? or even just the general plan here in plain terms?
I was able to put together a general rts style camera based on other code people have generously posted on the forum. But I’d still like to know whats going on here.