Skip to content
Snippets Groups Projects
Commit 219b291f authored by David Gilbert's avatar David Gilbert :bug:
Browse files

- Blueprints work now I think, there's a few weird things happening still but...

- Blueprints work now I think, there's a few weird things happening still but at least memory isn't exploding anymore.
- Serialization is not working correctly, a property needs to be changed for lines to display.
parent a4c4222e
Branches
No related tags found
No related merge requests found
...@@ -37,8 +37,7 @@ public class InstancedMeshLineRendering : ModuleRules ...@@ -37,8 +37,7 @@ public class InstancedMeshLineRendering : ModuleRules
{ {
"CoreUObject", "CoreUObject",
"Engine", "Engine",
"Slate", "RenderCore"
"SlateCore",
// ... add private dependencies that you statically link with here ... // ... add private dependencies that you statically link with here ...
} }
); );
......
...@@ -9,6 +9,19 @@ ...@@ -9,6 +9,19 @@
UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer) UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer)
{ {
NumCustomDataFloats = 5;
CurrentTextureMarker = FIntPoint(0, 0);
CurrentTextureIndex = 0,
NextFreeId = 0;
TextureWidth = 1024;
TextureHeight = 1024;
//PrimaryComponentTick.bCanEverTick = true;
//bTickInEditor = true;
//bAutoActivate = true;
SetWorldTransform(FTransform::Identity); SetWorldTransform(FTransform::Identity);
SetUsingAbsoluteLocation(true); SetUsingAbsoluteLocation(true);
...@@ -26,27 +39,10 @@ UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer& ...@@ -26,27 +39,10 @@ UGPUInstancedLineComponent::UGPUInstancedLineComponent(const FObjectInitializer&
SetMaterial(0, LineMaterial); SetMaterial(0, LineMaterial);
UMaterialInterface* LineMaterialInterface = LoadObject<UMaterialInterface>(NULL, TEXT("/InstancedMeshLineRendering/DynamicLineMaterial.DynamicLineMaterial"), NULL, LOAD_None, NULL); LineMaterialInterface = LoadObject<UMaterialInterface>(NULL, TEXT("/InstancedMeshLineRendering/DynamicLineMaterial.DynamicLineMaterial"), NULL, LOAD_None, NULL);
DynamicLineMaterial = UMaterialInstanceDynamic::Create(LineMaterialInterface, GetTransientPackage()); //DynamicLineMaterial = UMaterialInstanceDynamic::Create(LineMaterialInterface, GetTransientPackage());
check(DynamicLineMaterial); SetMaterial(0, DynamicLineMaterial);
// three color values + width + 1 texture index value
// r | g | b | w | i_T
NumCustomDataFloats = 5;
CurrentTextureMarker = FIntPoint(0, 0);
CurrentTextureIndex = 0,
NextFreeId = 0;
TextureWidth = 2048;
TextureHeight = 2048;
SetMobility(EComponentMobility::Static); SetMobility(EComponentMobility::Static);
//DynamicLineMaterial = nullptr;
//PositionTexture = nullptr;
} }
UGPUInstancedLineComponent::~UGPUInstancedLineComponent() UGPUInstancedLineComponent::~UGPUInstancedLineComponent()
...@@ -90,67 +86,34 @@ void UGPUInstancedLineComponent::UpdateWholeTexture() ...@@ -90,67 +86,34 @@ void UGPUInstancedLineComponent::UpdateWholeTexture()
void UGPUInstancedLineComponent::Init() void UGPUInstancedLineComponent::Init()
{ {
if(PositionTexture != nullptr) if (PositionTexture == nullptr)
{ {
UE_LOG(LogLineRendering, Error, TEXT("UGPUInstancedLineComponent::Init PositionTexture already exists!"));
}
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Creating Texture")); UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Creating Texture"));
PositionTexture = UTexture2D::CreateTransient(TextureWidth, TextureHeight, PF_A32B32G32R32F); PositionTexture = UTexture2D::CreateTransient(TextureWidth, TextureHeight, PF_A32B32G32R32F);
// Allocate the texture RHI //// Allocate the texture RHI
PositionTexture->UpdateResource(); PositionTexture->UpdateResource();
UpdateWholeTexture();
}
if (DynamicLineMaterial == nullptr) // FOR WHATEVER REASON I HAVE NO IDEA if (DynamicLineMaterial == nullptr) // FOR WHATEVER REASON I HAVE NO IDEA
{ {
UE_LOG(LogLineRendering, Fatal, TEXT("UGPUInstancedLineComponent::Init MID was nullptr!")); //UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init MID was nullptr!"));
DynamicLineMaterial = UMaterialInstanceDynamic::Create(LineMaterialInterface, GetTransientPackage());
SetMaterial(0, DynamicLineMaterial);
//check(DynamicLineMaterial);
//DynamicLineMaterial = CreateAndSetMaterialInstanceDynamic(0);
//DynamicLineMaterial->SetTextureParameterValue("PositionTexture", PositionTexture);
//DynamicLineMaterial->SetScalarParameterValue("TextureWidth", TextureWidth);
} }
else
{
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Setting MID"));
SetMaterial(0, DynamicLineMaterial);
DynamicLineMaterial->SetTextureParameterValue("PositionTexture", PositionTexture); DynamicLineMaterial->SetTextureParameterValue("PositionTexture", PositionTexture);
DynamicLineMaterial->SetScalarParameterValue("TextureWidth", TextureWidth); DynamicLineMaterial->SetScalarParameterValue("TextureWidth", TextureWidth);
} //UpdateWholeTexture();
//UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::Init Resetting Data"));
//LineMap.Empty();
//LinearLineData.Empty();
//NextFreeId = 0;
//CurrentTextureIndex = 0;
//CurrentTextureMarker = FIntPoint(0, 0);
//ClearInstances();
//RegisterSerializedEditorLines();
bIsInitialized = true; bIsInitialized = true;
//// Add serialized lines to be rendered immediately - pretty sure this could and should be done differently.
//for (FEditorLineData& EditorLine : EditorLines)
//{
// AddLineFromEditorData(EditorLine);
//}
// Update the texture
// Theoretically we could serialize the texture as well, but that seems like too much work
UpdateWholeTexture();
} }
//void UGPUInstancedLineComponent::RegisterSerializedEditorLines()
//{
//
// // Here's to hoping the respective id field doesn't get serialized...
//
// for (FEditorLineData& EditorLine : EditorLines)
// {
// if(EditorLine.RespectiveLineId == -1 || !LineMap.Contains(EditorLine.RespectiveLineId))
// {
// AddLineFromEditorData(EditorLine);
// }
// }
//}
void UGPUInstancedLineComponent::UpdateAllEditorLines() void UGPUInstancedLineComponent::UpdateAllEditorLines()
{ {
for (const FEditorLineData& EditorLine : EditorLines) for (const FEditorLineData& EditorLine : EditorLines)
...@@ -236,13 +199,10 @@ void UGPUInstancedLineComponent::BeginPlay() ...@@ -236,13 +199,10 @@ void UGPUInstancedLineComponent::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
// todo don't think this is needed here if(!PositionTexture)
//RegisterSerializedEditorLines();
//Init();
if(!bIsInitialized)
{ {
UE_LOG(LogLineRendering, Fatal, TEXT("UGPUInstancedLineComponent::BeginPlay: FATAL ERROR - Component is not initialized on BeginPlay!")); UE_LOG(LogLineRendering, Warning, TEXT("UGPUInstancedLineComponent::BeginPlay: Component is not initialized on BeginPlay, Initializing..."));
Init();
} }
} }
...@@ -250,15 +210,16 @@ void UGPUInstancedLineComponent::BeginPlay() ...@@ -250,15 +210,16 @@ void UGPUInstancedLineComponent::BeginPlay()
void UGPUInstancedLineComponent::PostInitProperties() void UGPUInstancedLineComponent::PostInitProperties()
{ {
Super::PostInitProperties(); Super::PostInitProperties();
if (FApp::CanEverRender() && !HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject)) //if (FApp::CanEverRender() && !HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::PostInitProperties IF")); //UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::PostInitProperties IF"));
} }
#if WITH_EDITOR #if WITH_EDITOR
void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
{ {
if (PropertyChangedEvent.Property != NULL && bIsInitialized) Init();
if (PropertyChangedEvent.Property != NULL)
{ {
if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UGPUInstancedLineComponent, EditorLines)) if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UGPUInstancedLineComponent, EditorLines))
{ {
...@@ -419,6 +380,7 @@ void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedCha ...@@ -419,6 +380,7 @@ void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedCha
void UGPUInstancedLineComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) void UGPUInstancedLineComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{ {
Init();
const FName PropertyName = PropertyChangedEvent.GetPropertyName(); const FName PropertyName = PropertyChangedEvent.GetPropertyName();
if (PropertyChangedEvent.Property != NULL) if (PropertyChangedEvent.Property != NULL)
...@@ -444,34 +406,65 @@ void UGPUInstancedLineComponent::OnUpdateTransform(EUpdateTransformFlags UpdateT ...@@ -444,34 +406,65 @@ void UGPUInstancedLineComponent::OnUpdateTransform(EUpdateTransformFlags UpdateT
{ {
SetWorldTransform(FTransform::Identity); SetWorldTransform(FTransform::Identity);
} }
TStructOnScope<FActorComponentInstanceData> UGPUInstancedLineComponent::GetComponentInstanceData() const
{
TStructOnScope<FActorComponentInstanceData> InstanceData;
#if WITH_EDITOR
InstanceData.InitializeAs<FUGPUInstancedLineComponentInstanceData>(this);
FUGPUInstancedLineComponentInstanceData* LineInstanceData = InstanceData.Cast<FUGPUInstancedLineComponentInstanceData>();
//LineInstanceData->PositionTexture = PositionTexture;
//LineInstanceData->DynamicMaterial = DynamicLineMaterial;
//LineInstanceData->LineMap = LineMap;
#endif
return InstanceData;
}
#endif
void UGPUInstancedLineComponent::ApplyComponentInstanceData(FUGPUInstancedLineComponentInstanceData* ComponentInstanceData)
{
#if WITH_EDITOR
//check(ComponentInstanceData);
//if(ComponentInstanceData->PositionTexture != nullptr)
// PositionTexture = ComponentInstanceData->PositionTexture;
//if (ComponentInstanceData->DynamicMaterial != nullptr)
//{
// DynamicLineMaterial = ComponentInstanceData->DynamicMaterial;
// DynamicLineMaterial->SetTextureParameterValue("PositionTexture", PositionTexture);
// DynamicLineMaterial->SetScalarParameterValue("TextureWidth", TextureWidth);
// SetMaterial(0, DynamicLineMaterial);
//}
//if (ComponentInstanceData->LineMap.Num() > 0)
// LineMap = ComponentInstanceData->LineMap;
#endif #endif
}
// Doesn't do anything yet, just as a testing function to see execution order on Unreal startup. // Doesn't do anything yet, just as a testing function to see execution order on Unreal startup.
void UGPUInstancedLineComponent::PostLoad() void UGPUInstancedLineComponent::PostLoad()
{ {
Super::PostLoad(); Super::PostLoad();
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::PostLoad")); //UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::PostLoad"));
if (FApp::CanEverRender() && !HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject)) //if (FApp::CanEverRender() && !IsTemplate())
{ //{
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::PostLoad IF")); //DynamicLineMaterial = UMaterialInstanceDynamic::Create(LineMaterialInterface, this);
//SetMaterial(0, DynamicLineMaterial);
if (!bIsInitialized) //}
Init();
}
} }
// Doesn't do anything yet, just as a testing function to see execution order on Unreal startup. // Doesn't do anything yet, just as a testing function to see execution order on Unreal startup.
void UGPUInstancedLineComponent::OnComponentCreated() void UGPUInstancedLineComponent::OnComponentCreated()
{ {
Super::OnComponentCreated(); Super::OnComponentCreated();
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::OnComponentCreated")); //UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::OnComponentCreated"));
if (FApp::CanEverRender() && !HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject)) //if (FApp::CanEverRender() && !IsTemplate())
{ //{
UE_LOG(LogLineRendering, Display, TEXT("UGPUInstancedLineComponent::OnComponentCreated IF")); // DynamicLineMaterial = UMaterialInstanceDynamic::Create(LineMaterialInterface, this);
// SetMaterial(0, DynamicLineMaterial);
if (!bIsInitialized) //}
Init();
}
} }
void UGPUInstancedLineComponent::BeginDestroy() void UGPUInstancedLineComponent::BeginDestroy()
...@@ -483,9 +476,6 @@ void UGPUInstancedLineComponent::BeginDestroy() ...@@ -483,9 +476,6 @@ void UGPUInstancedLineComponent::BeginDestroy()
void UGPUInstancedLineComponent::Serialize(FArchive& Ar) void UGPUInstancedLineComponent::Serialize(FArchive& Ar)
{ {
Super::Serialize(Ar); Super::Serialize(Ar);
} }
void UGPUInstancedLineComponent::ReserveMemory(int32 NumberOfSegments, int32 NumberOfLines) void UGPUInstancedLineComponent::ReserveMemory(int32 NumberOfSegments, int32 NumberOfLines)
...@@ -494,9 +484,6 @@ void UGPUInstancedLineComponent::ReserveMemory(int32 NumberOfSegments, int32 Num ...@@ -494,9 +484,6 @@ void UGPUInstancedLineComponent::ReserveMemory(int32 NumberOfSegments, int32 Num
PreAllocateInstancesMemory(Total); PreAllocateInstancesMemory(Total);
LineMap.Reserve(Total); LineMap.Reserve(Total);
LinearLineData.Reserve(NumberOfLines * (NumberOfSegments + 1)); LinearLineData.Reserve(NumberOfLines * (NumberOfSegments + 1));
// TODO: Texture size
} }
bool UGPUInstancedLineComponent::ResizeTexture(int32 Width, int32 Height) bool UGPUInstancedLineComponent::ResizeTexture(int32 Width, int32 Height)
......
...@@ -6,27 +6,6 @@ ...@@ -6,27 +6,6 @@
#include "Components/InstancedStaticMeshComponent.h" #include "Components/InstancedStaticMeshComponent.h"
#include "GPUInstancedLineComponent.generated.h" #include "GPUInstancedLineComponent.generated.h"
/**
*
*/
//typedef TPair<FVector, TTuple<int32, int32, int32>> GPULineSegment;
// Pair of InstanceId and LinearData index.
//
// LineArray that contains indices into the instance list and the linear data.
typedef TPair<int32, int32> GPULineIndices;
typedef TArray<GPULineIndices> GPULineArray;
// Maps a LineId to a LineArray.
typedef TMap<int32, GPULineArray> GPULinesMap;
USTRUCT(BlueprintType) USTRUCT(BlueprintType)
struct FEditorPoint struct FEditorPoint
...@@ -62,7 +41,7 @@ struct FEditorLineData ...@@ -62,7 +41,7 @@ struct FEditorLineData
UPROPERTY(EditAnywhere) UPROPERTY(EditAnywhere)
FColor Color; FColor Color;
UPROPERTY() UPROPERTY(VisibleAnywhere)
int32 RespectiveLineId = -1; int32 RespectiveLineId = -1;
FEditorLineData() FEditorLineData()
...@@ -116,7 +95,7 @@ class INSTANCEDMESHLINERENDERING_API UGPUInstancedLineComponent : public UInstan ...@@ -116,7 +95,7 @@ class INSTANCEDMESHLINERENDERING_API UGPUInstancedLineComponent : public UInstan
public: public:
UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer); UGPUInstancedLineComponent(const FObjectInitializer& ObjectInitializer);
~UGPUInstancedLineComponent(); virtual ~UGPUInstancedLineComponent();
virtual void BeginPlay() override; virtual void BeginPlay() override;
...@@ -126,9 +105,13 @@ public: ...@@ -126,9 +105,13 @@ public:
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; // need this for the widget as for some godforsaken reason the Chain event doesn't fire... virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; // need this for the widget as for some godforsaken reason the Chain event doesn't fire...
// This is ABSURDLY hacky // This is ABSURDLY hacky
virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) override; virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) override;
#endif #endif
virtual TStructOnScope<FActorComponentInstanceData> GetComponentInstanceData() const override;
/** Applies the cached component instance data to a newly blueprint constructed component. */
virtual void ApplyComponentInstanceData(struct FUGPUInstancedLineComponentInstanceData* ComponentInstanceData);
virtual void PostLoad() override; virtual void PostLoad() override;
virtual void OnComponentCreated() override; virtual void OnComponentCreated() override;
virtual void BeginDestroy() override; virtual void BeginDestroy() override;
...@@ -148,7 +131,6 @@ private: ...@@ -148,7 +131,6 @@ private:
} }
} }
void UpdateWholeTexture();
void Init(); void Init();
...@@ -162,6 +144,9 @@ public: ...@@ -162,6 +144,9 @@ public:
// todo // todo
void ReleaseData(); void ReleaseData();
void UpdateWholeTexture();
/** /**
* Reserves internal memory for a given amount of Lines and Segments per Line. * Reserves internal memory for a given amount of Lines and Segments per Line.
*/ */
...@@ -458,17 +443,20 @@ public: ...@@ -458,17 +443,20 @@ public:
UPROPERTY(BlueprintReadOnly, EditAnywhere) UPROPERTY(BlueprintReadOnly, EditAnywhere)
int32 TextureHeight; int32 TextureHeight;
UPROPERTY(transient) UPROPERTY(Transient)
UMaterialInstanceDynamic* DynamicLineMaterial; UMaterialInstanceDynamic* DynamicLineMaterial;
UPROPERTY(EditAnywhere, DisplayName = "Lines", meta = (MakeEditWidget = true, EditFixedOrder)) UPROPERTY(EditAnywhere, DisplayName = "Lines", meta = (MakeEditWidget = true, EditFixedOrder))
TArray<FEditorLineData> EditorLines; TArray<FEditorLineData> EditorLines;
private: UPROPERTY()
UMaterialInterface* LineMaterialInterface;
UPROPERTY() UPROPERTY()
TMap<int32, FGPULineArray> LineMap; TMap<int32, FGPULineArray> LineMap;
//private:
UPROPERTY() UPROPERTY()
TArray<FVector4> LinearLineData; TArray<FVector4> LinearLineData;
...@@ -487,5 +475,51 @@ private: ...@@ -487,5 +475,51 @@ private:
UPROPERTY() UPROPERTY()
FIntPoint CurrentTextureMarker; FIntPoint CurrentTextureMarker;
UPROPERTY(Transient)
bool bIsInitialized = false; bool bIsInitialized = false;
}; };
/** Helper class used to preserve texture pointer across blueprint reinstancing */
USTRUCT()
struct FUGPUInstancedLineComponentInstanceData : public FSceneComponentInstanceData
{
GENERATED_BODY()
public:
FUGPUInstancedLineComponentInstanceData() = default;
FUGPUInstancedLineComponentInstanceData(const UGPUInstancedLineComponent* InComponent)
: FSceneComponentInstanceData(InComponent)
, PositionTexture(InComponent->PositionTexture), LineMap(InComponent->LineMap)
{}
virtual ~FUGPUInstancedLineComponentInstanceData() = default;
virtual bool ContainsData() const override
{
return true;
}
virtual void ApplyToComponent(UActorComponent* Component, const ECacheApplyPhase CacheApplyPhase) override
{
Super::ApplyToComponent(Component, CacheApplyPhase);
CastChecked<UGPUInstancedLineComponent>(Component)->ApplyComponentInstanceData(this);
}
virtual void AddReferencedObjects(FReferenceCollector& Collector) override
{
Super::AddReferencedObjects(Collector);
Collector.AddReferencedObject(PositionTexture);
}
public:
//UPROPERTY()
UTexture2D* PositionTexture;
//UPROPERTY()
UMaterialInstanceDynamic* DynamicMaterial;
//UPROPERTY()
TMap<int32, FGPULineArray> LineMap;
};
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment