赞
踩
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); }
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; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。