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

- Added PostEditChangeProperty function to handle editor widget movement for point updates.

- Added helper functions to Add, Update and Delete/Clear Editor Lines, TODO: Insert.
- Fixed a bug in texture region calculation that lead to a crash.
parent 051b95eb
No related branches found
No related tags found
No related merge requests found
No preview for this file type
No preview for this file type
...@@ -127,6 +127,21 @@ void UGPUInstancedLineComponent::RegisterSerializedEditorLines() ...@@ -127,6 +127,21 @@ void UGPUInstancedLineComponent::RegisterSerializedEditorLines()
} }
} }
void UGPUInstancedLineComponent::UpdateAllEditorLines()
{
for (const FEditorLineData& EditorLine : EditorLines)
{
if (EditorLine.RespectiveLineId != -1)
{
UpdateLineFromEditorData(EditorLine);
}
else
{
UE_LOG(LogTemp, Error, TEXT("UGPUInstancedLineComponent::UpdateAllEditorLines : An editor line wasn't registered before updating it, ignoring!"));
}
}
}
FUpdateTextureRegion2D* UGPUInstancedLineComponent::CalculateTextureRegions(const FIntPoint& StartIndex, FUpdateTextureRegion2D* UGPUInstancedLineComponent::CalculateTextureRegions(const FIntPoint& StartIndex,
int32 NumberOfPoints, int32& NumberOfRegionsOut) int32 NumberOfPoints, int32& NumberOfRegionsOut)
{ {
...@@ -143,7 +158,7 @@ FUpdateTextureRegion2D* UGPUInstancedLineComponent::CalculateTextureRegions(cons ...@@ -143,7 +158,7 @@ FUpdateTextureRegion2D* UGPUInstancedLineComponent::CalculateTextureRegions(cons
(*Regions)[0].Width = FMath::Min(NumberOfPoints, TextureWidth); (*Regions)[0].Width = FMath::Min(NumberOfPoints, TextureWidth);
(*Regions)[0].Height = StartIndex.X == 0 ? (NumberOfPoints / TextureWidth) : 1; (*Regions)[0].Height = StartIndex.X == 0 ? (NumberOfPoints / TextureWidth) : 1;
RemainingPoints -= (*Regions)[0].Height == 1 ? ((*Regions)[0].Width - StartIndex.X) : (*Regions)[0].Width * (*Regions)[0].Height; RemainingPoints -= (*Regions)[0].Height == 1 ? (*Regions)[0].Width : (*Regions)[0].Width * (*Regions)[0].Height;
if(RemainingPoints == 0) if(RemainingPoints == 0)
{ {
NumberOfRegionsOut = 1; NumberOfRegionsOut = 1;
...@@ -234,10 +249,13 @@ void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedCha ...@@ -234,10 +249,13 @@ void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedCha
const int32 RemovedAtIndex = PropertyChangedEvent.GetArrayIndex(PropertyChangedEvent.Property->GetFName().ToString()); const int32 RemovedAtIndex = PropertyChangedEvent.GetArrayIndex(PropertyChangedEvent.Property->GetFName().ToString());
check(RemovedAtIndex != INDEX_NONE); check(RemovedAtIndex != INDEX_NONE);
RemoveLine(EditorLines[RemovedAtIndex].RespectiveLineId); // todo test me, depends on if the data was removed already or not RemoveLineFromEditorData(EditorLineIds[RemovedAtIndex]);
//RemoveLine(EditorLines[RemovedAtIndex].RespectiveLineId);
// todo test me, depends on if the data was removed already or not - the data seems to be already removed
} }
else if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ArrayClear) else if (PropertyChangedEvent.ChangeType == EPropertyChangeType::ArrayClear)
{ {
RemoveAllEditorLines();
} }
} }
else if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(FEditorLineData, Points)) else if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(FEditorLineData, Points))
...@@ -267,6 +285,28 @@ void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedCha ...@@ -267,6 +285,28 @@ void UGPUInstancedLineComponent::PostEditChangeChainProperty(FPropertyChangedCha
} }
Super::PostEditChangeChainProperty(PropertyChangedEvent); Super::PostEditChangeChainProperty(PropertyChangedEvent);
} }
void UGPUInstancedLineComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
const FName PropertyName = PropertyChangedEvent.GetPropertyName();
if (PropertyChangedEvent.Property != NULL)
{
if (PropertyName == GET_MEMBER_NAME_CHECKED(FEditorPoint, Point))
{
if(PropertyChangedEvent.ChangeType == EPropertyChangeType::Unspecified)
{
// Due to not having access to the chain whenever the widget is used, we need to just update ALL the editor lines every time
// the widget is dragged around. This is incredibly annoying but there doesn't seem to be another way, as the widget drag doesn't fire
// the PostEditChangeChainProperty callback.
UpdateAllEditorLines();
}
}
}
Super::PostEditChangeProperty(PropertyChangedEvent);
}
#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.
...@@ -440,6 +480,7 @@ int32 UGPUInstancedLineComponent::AddLineFromEditorData(FEditorLineData& LineDat ...@@ -440,6 +480,7 @@ int32 UGPUInstancedLineComponent::AddLineFromEditorData(FEditorLineData& LineDat
const TArray<FVector>* FVectorLineDataPtr = reinterpret_cast<const TArray<FVector>*>(EditorLineDataPtr); const TArray<FVector>* FVectorLineDataPtr = reinterpret_cast<const TArray<FVector>*>(EditorLineDataPtr);
LineData.RespectiveLineId = AddLine(*FVectorLineDataPtr, LineData.Color, LineData.Width); LineData.RespectiveLineId = AddLine(*FVectorLineDataPtr, LineData.Color, LineData.Width);
EditorLineIds.Add(LineData.RespectiveLineId);
return LineData.RespectiveLineId; return LineData.RespectiveLineId;
} }
...@@ -927,6 +968,14 @@ bool UGPUInstancedLineComponent::UpdateLinesDataDirectly(int32 LineIdStart, TArr ...@@ -927,6 +968,14 @@ bool UGPUInstancedLineComponent::UpdateLinesDataDirectly(int32 LineIdStart, TArr
return true; return true;
} }
bool UGPUInstancedLineComponent::UpdateLineFromEditorData(const FEditorLineData& LineData)
{
TArray<FVector> Points;
Points.SetNumUninitialized(LineData.Points.Num());
FMemory::Memcpy(Points.GetData(), LineData.Points.GetData(), sizeof(FVector) * LineData.Points.Num());
return UpdateLine(LineData.RespectiveLineId, Points);
}
bool UGPUInstancedLineComponent::DrawLinesDirectly(int32 LineIdStart, TArray<FVector4>& Points) bool UGPUInstancedLineComponent::DrawLinesDirectly(int32 LineIdStart, TArray<FVector4>& Points)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::DrawLinesDirectly")) TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::DrawLinesDirectly"))
...@@ -1108,6 +1157,32 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId) ...@@ -1108,6 +1157,32 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
return true; return true;
} }
bool UGPUInstancedLineComponent::RemoveLineFromEditorData(int32 LineId)
{
int32 Index = 0;
if (EditorLineIds.Find(LineId, Index))
{
RemoveLine(LineId);
EditorLineIds.RemoveAt(Index);
}
return false;
}
bool UGPUInstancedLineComponent::RemoveAllEditorLines()
{
for(const int32 Id : EditorLineIds)
{
RemoveLine(Id);
}
if(EditorLines.Num() != 0)
{
EditorLines.Empty();
UE_LOG(LogTemp, Display, TEXT("UGPUInstancedLineComponent::RemoveAllEditorLines - EditorLines wasn't empty already, clearing."));
}
EditorLineIds.Empty();
return true;
}
bool UGPUInstancedLineComponent::RemovePoint(int32 LineId, int32 PointId) bool UGPUInstancedLineComponent::RemovePoint(int32 LineId, int32 PointId)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::RemoveLine")) TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::RemoveLine"))
......
...@@ -75,7 +75,7 @@ struct FEditorLineData ...@@ -75,7 +75,7 @@ struct FEditorLineData
}; };
UCLASS(Blueprintable, BlueprintType, meta = (BlueprintSpawnableComponent)) UCLASS(Blueprintable, BlueprintType, meta = (BlueprintSpawnableComponent), HideCategories=("Instances"))
class INSTANCEDMESHLINERENDERING_API UGPUInstancedLineComponent : public UInstancedStaticMeshComponent class INSTANCEDMESHLINERENDERING_API UGPUInstancedLineComponent : public UInstancedStaticMeshComponent
{ {
GENERATED_BODY() GENERATED_BODY()
...@@ -99,12 +99,19 @@ private: ...@@ -99,12 +99,19 @@ private:
void RegisterSerializedEditorLines(); void RegisterSerializedEditorLines();
void UpdateAllEditorLines();
FUpdateTextureRegion2D* CalculateTextureRegions(const FIntPoint& StartIndex, int32 NumberOfPoints, int32& NumberOfRegionsOut); FUpdateTextureRegion2D* CalculateTextureRegions(const FIntPoint& StartIndex, int32 NumberOfPoints, int32& NumberOfRegionsOut);
GPULinesMap LineMap; GPULinesMap LineMap;
TArray<FVector4> LinearLineData; TArray<FVector4> LinearLineData;
// Array that keeps track of editor lines. This is ONLY needed because the array can be cleared by a simple stupid button press in the
// details panel, circumventing the PostEditChangeChainProperty function by clearing the array first. The change callback gets called, but
// as the EditorLines array has already been cleared, it's not possible to backtrack the removed lines.
TArray<int32> EditorLineIds;
int32 NextFreeId = 0; int32 NextFreeId = 0;
int32 CurrentTextureIndex; int32 CurrentTextureIndex;
FIntPoint CurrentTextureMarker; FIntPoint CurrentTextureMarker;
...@@ -117,6 +124,7 @@ protected: ...@@ -117,6 +124,7 @@ protected:
virtual void PostInitProperties() override; virtual void PostInitProperties() override;
#if WITH_EDITOR #if WITH_EDITOR
virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override; virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override;
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; // need this for the widget as for some godforsaken reason the Chain event doesn't fire...
#endif #endif
virtual void PostLoad() override; virtual void PostLoad() override;
...@@ -268,6 +276,15 @@ public: ...@@ -268,6 +276,15 @@ public:
*/ */
bool UpdateLinesDataDirectly(int32 LineIdStart, TArray<FVector4>& Points); bool UpdateLinesDataDirectly(int32 LineIdStart, TArray<FVector4>& Points);
/**
* Updates a line from a FEditorLineData struct and returns true on success.
*
* @param LineData [in] The Line data stored in a FEditorLineData struct.
*
* @return bool Returns true on successful update.
*/
UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent")
bool UpdateLineFromEditorData(const FEditorLineData& LineData);
/** /**
* Fast function to draw the specified lines directly WITHOUT UPDATING THE INTERNAL LINE STATE. * Fast function to draw the specified lines directly WITHOUT UPDATING THE INTERNAL LINE STATE.
...@@ -303,6 +320,14 @@ public: ...@@ -303,6 +320,14 @@ public:
UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent") UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent")
bool RemoveLine(int32 LineId); bool RemoveLine(int32 LineId);
UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent")
bool RemoveLineFromEditorData(int32 LineId);
UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent")
bool RemoveAllEditorLines();
// todo // todo
UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent") UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent")
bool RemovePoint(int32 LineId, int32 PointId); bool RemovePoint(int32 LineId, int32 PointId);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment