Last active
January 17, 2025 03:22
-
-
Save tilongzs/a233eca957551c0106d155ce6cd2cd36 to your computer and use it in GitHub Desktop.
(Unreal Engine)场景捕捉组件2D坐标与世界坐标的相互转换
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Components/SceneCaptureComponent2D.h" | |
#include "Engine/TextureRenderTarget2D.h" | |
void ProjectSceneCaptureToWorld(const class USceneCaptureComponent2D* sceneCaptureCompone2D, const FVector2D& sceneCapturePosition, FVector& worldPosition, FVector& worldDirection) | |
{ | |
// 计算视口矩阵 | |
const FTransform& transform = sceneCaptureCompone2D->GetComponentToWorld(); | |
FMatrix viewMatrix = transform.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 = sceneCaptureCompone2D->FOVAngle * (float)PI / 360.0f; | |
FIntPoint captureSize(sceneCaptureCompone2D->TextureTarget->GetSurfaceWidth(), sceneCaptureCompone2D->TextureTarget->GetSurfaceHeight()); | |
float XAxisMultiplier; | |
float YAxisMultiplier; | |
if (captureSize.X > captureSize.Y) | |
{ | |
XAxisMultiplier = 1.0f; | |
YAxisMultiplier = captureSize.X / (float)captureSize.Y; | |
} | |
else | |
{ | |
XAxisMultiplier = captureSize.Y / (float)captureSize.X; | |
YAxisMultiplier = 1.0f; | |
} | |
FMatrix projectionMatrix = FReversedZPerspectiveMatrix(FOV, FOV, XAxisMultiplier, YAxisMultiplier, GNearClippingPlane, GNearClippingPlane); | |
const FMatrix inverseViewMatrix = viewMatrix.InverseFast(); | |
const FMatrix invProjectionMatrix = projectionMatrix.Inverse(); | |
const FIntRect viewRect = FIntRect(0, 0, captureSize.X, captureSize.Y); | |
FSceneView::DeprojectScreenToWorld(sceneCapturePosition, viewRect, inverseViewMatrix, invProjectionMatrix, worldPosition, worldDirection); | |
} | |
bool ProjectWorldToSceneCapture(const FVector& worldPosition, const class USceneCaptureComponent2D* sceneCaptureCompone2D, FVector2D& sceneCapturePosition) | |
{ | |
// 计算视口矩阵 | |
const FTransform& transform = sceneCaptureCompone2D->GetComponentToWorld(); | |
FMatrix viewMatrix = transform.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 = sceneCaptureCompone2D->FOVAngle * (float)PI / 360.0f; | |
FIntPoint captureSize(sceneCaptureCompone2D->TextureTarget->GetSurfaceWidth(), sceneCaptureCompone2D->TextureTarget->GetSurfaceHeight()); | |
float XAxisMultiplier; | |
float YAxisMultiplier; | |
if (captureSize.X > captureSize.Y) | |
{ | |
XAxisMultiplier = 1.0f; | |
YAxisMultiplier = captureSize.X / (float)captureSize.Y; | |
} | |
else | |
{ | |
XAxisMultiplier = captureSize.Y / (float)captureSize.X; | |
YAxisMultiplier = 1.0f; | |
} | |
FMatrix projectionMatrix = FReversedZPerspectiveMatrix(FOV, FOV, XAxisMultiplier, YAxisMultiplier, GNearClippingPlane, GNearClippingPlane); | |
FMatrix viewProjectionMatrix = viewMatrix * projectionMatrix; | |
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; | |
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; | |
FVector2D rayStartViewRectSpace( | |
(normalizedX * (float)viewRect.Width()), | |
(normalizedY * (float)viewRect.Height()) | |
); | |
sceneCapturePosition = rayStartViewRectSpace + FVector2D(static_cast<float>(viewRect.Min.X), static_cast<float>(viewRect.Min.Y)); | |
return true; | |
} | |
return false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment