UE C++ 相机视口变换(World与相机互转)

UE C++ 相机视口变换(World与相机互转)

cpp 复制代码
UFUNCTION(BlueprintCallable, BlueprintPure)
static void ProjectSceneCaptureToWorld(const class USceneCaptureComponent2D* SceneCaptureComponent2D,
                                       const FVector2D& SceneCapturePosition, FVector& WorldPosition,
                                       FVector& WorldDirection)
{
	if (!IsValid(SceneCaptureComponent2D))
	{
		return;
	}
	// 视口矩阵
	const FTransform& ViewTransform = SceneCaptureComponent2D->GetComponentToWorld();
	FMatrix ViewMatrix = ViewTransform.ToInverseMatrixWithScale();
	ViewMatrix = ViewMatrix * FMatrix(FPlane(0, 0, 1, 0), FPlane(1, 0, 0, 0), FPlane(0, 1, 0, 0),
	                                  FPlane(0, 0, 0, 1));
	const float FOV = SceneCaptureComponent2D->FOVAngle * (float)PI / 360.0f;
	const FIntPoint CaptureSize(SceneCaptureComponent2D->TextureTarget->GetSurfaceWidth(),
	                            SceneCaptureComponent2D->TextureTarget->GetSurfaceHeight());
	float XAxisMultiplier;
	float YAxisMultiplier;
	if (CaptureSize.X > CaptureSize.Y)
	{
		XAxisMultiplier = 1.0f;
		YAxisMultiplier = CaptureSize.X / static_cast<float>(CaptureSize.Y);
	}
	else
	{
		XAxisMultiplier = CaptureSize.Y / static_cast<float>(CaptureSize.X);
		YAxisMultiplier = 1.0f;
	}
	// 投影矩阵
	const FMatrix ProjectionMatrix = FReversedZPerspectiveMatrix(FOV, FOV, XAxisMultiplier, YAxisMultiplier,
	                                                             GNearClippingPlane, GNearClippingPlane);
	//视口矩阵与投影矩阵的逆矩阵                                                           
	const FMatrix InverseViewMatrix = ViewMatrix.InverseFast();
	const FMatrix InverseProjectionMatrix = ProjectionMatrix.Inverse();

	const FIntRect ViewRect = FIntRect(0, 0, CaptureSize.X, CaptureSize.Y);
	FSceneView::DeprojectScreenToWorld(SceneCapturePosition, ViewRect, InverseViewMatrix, InverseProjectionMatrix,
	                                   WorldPosition, WorldDirection);
}
cpp 复制代码
	UFUNCTION(BlueprintCallable, BlueprintPure)
	static bool ProjectWorldToSceneCapture(const FVector& WorldPosition,
	                                       const class USceneCaptureComponent2D* SceneCaptureComponent2D,
	                                       FVector2D& SceneCapturePosition)
	{
		if (!IsValid(SceneCaptureComponent2D))
		{
			return false;
		}
		//视口矩阵
		const FTransform& ViewTransform = SceneCaptureComponent2D->GetComponentToWorld();
		FMatrix ViewMatrix = ViewTransform.ToInverseMatrixWithScale();
		ViewMatrix = ViewMatrix * FMatrix(FPlane(0, 0, 1, 0), FPlane(1, 0, 0, 0), FPlane(0, 1, 0, 0),
		                                  FPlane(0, 0, 0, 1));
		                                  
		const float FOV = SceneCaptureComponent2D->FOVAngle * (float)PI / 360.0f;
		const FIntPoint CaptureSize(SceneCaptureComponent2D->TextureTarget->GetSurfaceWidth(),
		                            SceneCaptureComponent2D->TextureTarget->GetSurfaceHeight());
		float XAxisMultiplier;
		float YAxisMultiplier;
		if (CaptureSize.X > CaptureSize.Y)
		{
			XAxisMultiplier = 1.0f;
			YAxisMultiplier = CaptureSize.X / static_cast<float>(CaptureSize.Y);
		}
		else
		{
			XAxisMultiplier = CaptureSize.Y / static_cast<float>(CaptureSize.X);
			YAxisMultiplier = 1.0f;
		}
		// 投影矩阵
		const FMatrix ProjectionMatrix = FReversedZPerspectiveMatrix(FOV, FOV, XAxisMultiplier, YAxisMultiplier,
		                                                             GNearClippingPlane, GNearClippingPlane);
		const FMatrix ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;
		const FPlane Result = ViewProjectionMatrix.TransformFVector4(FVector4(WorldPosition, 1.f));
		const FIntRect viewRect = FIntRect(0, 0, CaptureSize.X, CaptureSize.Y);
		if (Result.W > 0.0f)
		{
			// the result of this will be x and y coords in -1..1 projection space
			const float RHW = 1.0f / Result.W;
			const FPlane PosInScreenSpace = FPlane(Result.X * RHW, Result.Y * RHW, Result.Z * RHW, Result.W);

			// Move from projection space to normalized 0..1 UI space
			const float NormalizedX = (PosInScreenSpace.X / 2.f) + 0.5f;
			const float NormalizedY = 1.f - (PosInScreenSpace.Y / 2.f) - 0.5f;

			const FVector2D RayStartViewRectSpace(
				(NormalizedX * static_cast<float>(viewRect.Width())),
				(NormalizedY * static_cast<float>(viewRect.Height()))
			);

			SceneCapturePosition = RayStartViewRectSpace + FVector2D(static_cast<float>(viewRect.Min.X),
			                                                         static_cast<float>(viewRect.Min.Y));

			return true;
		}
		return false;
	}
相关推荐
我们的五年7 分钟前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
zwjapple15 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five16 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
前端每日三省18 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
凡人的AI工具箱31 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
做人不要太理性34 分钟前
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
c++·哈希算法·散列表·unordered_map·unordered_set
程序员-King.43 分钟前
2、桥接模式
c++·桥接模式
chnming19871 小时前
STL关联式容器之map
开发语言·c++
进击的六角龙1 小时前
深入浅出:使用Python调用API实现智能天气预报
开发语言·python
檀越剑指大厂1 小时前
【Python系列】浅析 Python 中的字典更新与应用场景
开发语言·python