Clean up and document code
This commit is contained in:
parent
8dc892b9fa
commit
5cc5b232cb
@ -1,73 +1,129 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "LRRenderUtilLibrary.h"
|
#include "LRRenderUtilLibrary.h"
|
||||||
|
|
||||||
#include "Components/SceneCaptureComponent2D.h"
|
#include "Components/SceneCaptureComponent2D.h"
|
||||||
#include "Engine/TextureRenderTarget2D.h"
|
#include "Engine/TextureRenderTarget2D.h"
|
||||||
#include "Kismet/KismetRenderingLibrary.h"
|
#include "Kismet/KismetRenderingLibrary.h"
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
#include "Engine/World.h"
|
||||||
|
|
||||||
void ULRRenderUtilLibrary::SetupSceneCaptureForMesh(USceneCaptureComponent2D* SceneCapture, UStaticMeshComponent* MeshComp)
|
void ULRRenderUtilLibrary::SetupSceneCaptureForMesh(
|
||||||
|
USceneCaptureComponent2D* SceneCapture,
|
||||||
|
UStaticMeshComponent* MeshComp,
|
||||||
|
TEnumAsByte<enum ESceneCaptureSource> CaptureSource)
|
||||||
{
|
{
|
||||||
if (!SceneCapture || !MeshComp)
|
if (!SceneCapture || !MeshComp)
|
||||||
{
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("SetupSceneCaptureForMesh: Invalid SceneCapture or MeshComp"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MeshComp->IsValidLowLevel())
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("SetupSceneCaptureForMesh: MeshComp is not valid"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the scene capture to focus on the mesh
|
// Set the scene capture to focus on the mesh
|
||||||
SceneCapture->ShowOnlyComponent(MeshComp);
|
SceneCapture->ShowOnlyComponent(MeshComp);
|
||||||
|
|
||||||
SceneCapture->CaptureSource = ESceneCaptureSource::SCS_BaseColor;
|
SceneCapture->CaptureSource = CaptureSource;
|
||||||
SceneCapture->bCaptureEveryFrame = false;
|
SceneCapture->bCaptureEveryFrame = false;
|
||||||
SceneCapture->bCaptureOnMovement = false;
|
SceneCapture->bCaptureOnMovement = false;
|
||||||
SceneCapture->FOVAngle = 90.f;
|
SceneCapture->FOVAngle = 90.f;
|
||||||
|
|
||||||
// Set a solid background color (black by default)
|
// Set a solid background color
|
||||||
SceneCapture->CompositeMode = ESceneCaptureCompositeMode::SCCM_Overwrite;
|
SceneCapture->CompositeMode = ESceneCaptureCompositeMode::SCCM_Overwrite;
|
||||||
|
|
||||||
|
// Ensure we have a valid texture target
|
||||||
|
if (SceneCapture->TextureTarget)
|
||||||
|
{
|
||||||
SceneCapture->TextureTarget->ClearColor = FLinearColor::Transparent;
|
SceneCapture->TextureTarget->ClearColor = FLinearColor::Transparent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("SetupSceneCaptureForMesh: TextureTarget is null"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust the transform to frame the mesh
|
// Adjust the transform to frame the mesh
|
||||||
FVector MeshBounds = MeshComp->Bounds.BoxExtent;
|
FVector MeshBounds = MeshComp->Bounds.BoxExtent;
|
||||||
FVector MeshOrigin = MeshComp->Bounds.Origin;
|
FVector MeshOrigin = MeshComp->Bounds.Origin;
|
||||||
|
|
||||||
// Calculate the camera distance
|
// Calculate the camera distance based on mesh size
|
||||||
float CameraDistance = MeshBounds.Size() * 1.1f; // Adjust multiplier as needed
|
float MaxExtent = FMath::Max3(MeshBounds.X, MeshBounds.Y, MeshBounds.Z);
|
||||||
|
float CameraDistance = MaxExtent * 2.5f; // Adjusted to ensure mesh fits in view
|
||||||
|
|
||||||
// Calculate the camera location
|
// Calculate the camera location - position from front of mesh (+X axis)
|
||||||
FVector CameraLocation = MeshOrigin + FVector(CameraDistance, 0.f, 0.f); // Default to capturing from the +X axis
|
FVector CameraLocation = MeshOrigin + FVector(CameraDistance, 0.f, 0.f);
|
||||||
|
|
||||||
// Calculate the camera rotation
|
// Calculate the camera rotation to look at mesh center
|
||||||
FRotator CameraRotation = (MeshOrigin - CameraLocation).Rotation();
|
FRotator CameraRotation = (MeshOrigin - CameraLocation).Rotation();
|
||||||
|
|
||||||
SceneCapture->SetWorldLocationAndRotation(CameraLocation, CameraRotation); // Adjust rotation as needed
|
SceneCapture->SetWorldLocationAndRotation(CameraLocation, CameraRotation);
|
||||||
|
|
||||||
|
// Register component to make sure it will render
|
||||||
|
if (!SceneCapture->IsRegistered())
|
||||||
|
{
|
||||||
|
SceneCapture->RegisterComponent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UTextureRenderTarget2D* ULRRenderUtilLibrary::CaptureMeshToRenderTarget(UStaticMeshComponent* MeshComp, const FVector2D& ImageSize, UObject* WorldContextObject)
|
UTextureRenderTarget2D* ULRRenderUtilLibrary::CaptureMeshToRenderTarget(
|
||||||
|
UStaticMeshComponent* MeshComp,
|
||||||
|
const FVector2D& ImageSize,
|
||||||
|
UObject* WorldContextObject,
|
||||||
|
TEnumAsByte<enum ESceneCaptureSource> CaptureSource)
|
||||||
{
|
{
|
||||||
if (!MeshComp || !WorldContextObject)
|
if (!MeshComp || !WorldContextObject || !WorldContextObject->GetWorld())
|
||||||
{
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CaptureMeshToRenderTarget: Invalid parameters"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a render target
|
// Create a render target with proper size
|
||||||
UTextureRenderTarget2D* RenderTarget = UKismetRenderingLibrary::CreateRenderTarget2D(
|
UTextureRenderTarget2D* RenderTarget = UKismetRenderingLibrary::CreateRenderTarget2D(
|
||||||
WorldContextObject, ImageSize.X, ImageSize.Y, ETextureRenderTargetFormat::RTF_RGBA8);
|
WorldContextObject,
|
||||||
|
FMath::Max(32, static_cast<int32>(ImageSize.X)),
|
||||||
|
FMath::Max(32, static_cast<int32>(ImageSize.Y)),
|
||||||
|
ETextureRenderTargetFormat::RTF_RGBA8);
|
||||||
|
|
||||||
if (!RenderTarget)
|
if (!RenderTarget)
|
||||||
{
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CaptureMeshToRenderTarget: Failed to create render target"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a temporary actor to hold the scene capture component
|
// Create a temporary actor to hold the scene capture component
|
||||||
AActor* TempActor = WorldContextObject->GetWorld()->SpawnActor<AActor>();
|
AActor* TempActor = WorldContextObject->GetWorld()->SpawnActor<AActor>();
|
||||||
|
if (!TempActor)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CaptureMeshToRenderTarget: Failed to spawn temporary actor"));
|
||||||
|
return RenderTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a root component if it doesn't exist
|
||||||
|
if (!TempActor->GetRootComponent())
|
||||||
|
{
|
||||||
|
USceneComponent* RootComponent = NewObject<USceneComponent>(TempActor, TEXT("RootComponent"));
|
||||||
|
TempActor->SetRootComponent(RootComponent);
|
||||||
|
RootComponent->RegisterComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and set up scene capture component
|
||||||
USceneCaptureComponent2D* SceneCapture = NewObject<USceneCaptureComponent2D>(TempActor);
|
USceneCaptureComponent2D* SceneCapture = NewObject<USceneCaptureComponent2D>(TempActor);
|
||||||
|
if (SceneCapture)
|
||||||
|
{
|
||||||
|
SceneCapture->RegisterComponent();
|
||||||
SceneCapture->AttachToComponent(TempActor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
|
SceneCapture->AttachToComponent(TempActor->GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
|
||||||
SceneCapture->TextureTarget = RenderTarget;
|
SceneCapture->TextureTarget = RenderTarget;
|
||||||
|
|
||||||
// Setup the scene capture
|
// Setup the scene capture
|
||||||
SetupSceneCaptureForMesh(SceneCapture, MeshComp);
|
SetupSceneCaptureForMesh(SceneCapture, MeshComp, CaptureSource);
|
||||||
|
|
||||||
UKismetRenderingLibrary::ClearRenderTarget2D(WorldContextObject, SceneCapture->TextureTarget, FLinearColor::Transparent);
|
// Clear the render target
|
||||||
|
UKismetRenderingLibrary::ClearRenderTarget2D(WorldContextObject, RenderTarget, FLinearColor::Transparent);
|
||||||
|
|
||||||
// Disable post-processing effects
|
// Disable post-processing effects
|
||||||
SceneCapture->PostProcessSettings.bOverride_AutoExposureMethod = true;
|
SceneCapture->PostProcessSettings.bOverride_AutoExposureMethod = true;
|
||||||
@ -80,8 +136,45 @@ UTextureRenderTarget2D* ULRRenderUtilLibrary::CaptureMeshToRenderTarget(UStaticM
|
|||||||
// Trigger a one-time capture
|
// Trigger a one-time capture
|
||||||
SceneCapture->CaptureScene();
|
SceneCapture->CaptureScene();
|
||||||
|
|
||||||
|
// Force the GPU to complete rendering
|
||||||
|
FlushRenderingCommands();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CaptureMeshToRenderTarget: Failed to create scene capture component"));
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up the temporary actor
|
// Clean up the temporary actor
|
||||||
TempActor->Destroy();
|
TempActor->Destroy();
|
||||||
|
|
||||||
return RenderTarget;
|
return RenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ULRRenderUtilLibrary::CaptureSceneNow(USceneCaptureComponent2D* SceneCapture)
|
||||||
|
{
|
||||||
|
if (!SceneCapture || !SceneCapture->IsValidLowLevel())
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CaptureSceneNow: Invalid scene capture component"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SceneCapture->TextureTarget)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("CaptureSceneNow: Scene capture has no texture target"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure component is registered
|
||||||
|
if (!SceneCapture->IsRegistered())
|
||||||
|
{
|
||||||
|
SceneCapture->RegisterComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger the capture
|
||||||
|
SceneCapture->CaptureScene();
|
||||||
|
|
||||||
|
// Force the GPU to complete rendering
|
||||||
|
FlushRenderingCommands();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -6,20 +6,52 @@
|
|||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
#include "LRRenderUtilLibrary.generated.h"
|
#include "LRRenderUtilLibrary.generated.h"
|
||||||
|
|
||||||
|
class USceneCaptureComponent2D;
|
||||||
|
class UTextureRenderTarget2D;
|
||||||
|
class UStaticMeshComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Utility library for capturing and rendering objects in the Lucky Robots system
|
||||||
*/
|
*/
|
||||||
UCLASS()
|
UCLASS(BlueprintType, Blueprintable)
|
||||||
class LUCKYWORLDV2_API ULRRenderUtilLibrary : public UBlueprintFunctionLibrary
|
class LUCKYWORLDV2_API ULRRenderUtilLibrary : public UBlueprintFunctionLibrary
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Captures a static mesh component to a render target texture
|
||||||
|
* @param MeshComp The static mesh component to capture
|
||||||
|
* @param ImageSize The size of the output image
|
||||||
|
* @param WorldContextObject The world context
|
||||||
|
* @param CaptureSource The type of data to capture (default is BaseColor)
|
||||||
|
* @return The rendered texture
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Lucky Robots|Render Utilities")
|
||||||
|
static UTextureRenderTarget2D* CaptureMeshToRenderTarget(
|
||||||
|
UStaticMeshComponent* MeshComp,
|
||||||
|
const FVector2D& ImageSize,
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Render Utilities")
|
UObject* WorldContextObject,
|
||||||
UTextureRenderTarget2D* CaptureMeshToRenderTarget(UStaticMeshComponent* MeshComp, const FVector2D& ImageSize, UObject* WorldContextObject);
|
TEnumAsByte<enum ESceneCaptureSource> CaptureSource = ESceneCaptureSource::SCS_BaseColor);
|
||||||
|
|
||||||
private:
|
/**
|
||||||
void SetupSceneCaptureForMesh(USceneCaptureComponent2D* SceneCapture, UStaticMeshComponent* MeshComp);
|
* Sets up a scene capture component to focus on a specific mesh
|
||||||
|
* @param SceneCapture The scene capture component to set up
|
||||||
|
* @param MeshComp The static mesh component to focus on
|
||||||
|
* @param CaptureSource The type of data to capture (default is BaseColor)
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Lucky Robots|Render Utilities")
|
||||||
|
static void SetupSceneCaptureForMesh(
|
||||||
|
USceneCaptureComponent2D* SceneCapture,
|
||||||
|
UStaticMeshComponent* MeshComp,
|
||||||
|
TEnumAsByte<enum ESceneCaptureSource> CaptureSource = ESceneCaptureSource::SCS_BaseColor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures the current view of a scene capture component to its render target
|
||||||
|
* @param SceneCapture The scene capture component to trigger
|
||||||
|
* @return Success status
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Lucky Robots|Render Utilities")
|
||||||
|
static bool CaptureSceneNow(USceneCaptureComponent2D* SceneCapture);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user