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

- Removed Custom Data test actor, as the issue has been fixed in 4.25.

- Fixed a bug with color custom data.
- Added update functions for Points, needs to be tested.
- Fixed remove line function to correctly delete the instances, as RemoveInstance actually shrinks the ids. This is a slow operation currently.
parent 516eb548
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
File deleted
No preview for this file type
File deleted
No preview for this file type
...@@ -280,7 +280,7 @@ int32 UGPUInstancedLineComponent::AddLine(const TArray<FVector>& Line, FLinearCo ...@@ -280,7 +280,7 @@ int32 UGPUInstancedLineComponent::AddLine(const TArray<FVector>& Line, FLinearCo
int32 InstanceId = AddInstanceWorldSpace(FTransform::Identity); int32 InstanceId = AddInstanceWorldSpace(FTransform::Identity);
SetCustomDataValue(InstanceId, 0, Color.R, false); SetCustomDataValue(InstanceId, 0, Color.R, false);
SetCustomDataValue(InstanceId, 1, Color.G, false); SetCustomDataValue(InstanceId, 1, Color.G, false);
SetCustomDataValue(InstanceId, 2, static_cast<float>(InstanceId)/*Color.B*/, false); SetCustomDataValue(InstanceId, 2, Color.B, false);
SetCustomDataValue(InstanceId, 3, Width, false); SetCustomDataValue(InstanceId, 3, Width, false);
SetCustomDataValue(InstanceId, 4, static_cast<float>(CurrentTextureIndex), false); // Segment Start SetCustomDataValue(InstanceId, 4, static_cast<float>(CurrentTextureIndex), false); // Segment Start
NewLineArray.Add(TPair<int32, int32>{InstanceId, LinearLineData.Num() + PointIndex}); NewLineArray.Add(TPair<int32, int32>{InstanceId, LinearLineData.Num() + PointIndex});
...@@ -732,6 +732,7 @@ bool UGPUInstancedLineComponent::InsertPoints(int32 LineId, int32 SegmentId, con ...@@ -732,6 +732,7 @@ bool UGPUInstancedLineComponent::InsertPoints(int32 LineId, int32 SegmentId, con
return true; return true;
} }
// todo test this not sure if it actually works
bool UGPUInstancedLineComponent::UpdateLine(int32 LineId, TArray<FVector>& Points) bool UGPUInstancedLineComponent::UpdateLine(int32 LineId, TArray<FVector>& Points)
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::UpdateLine")) TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::UpdateLine"))
...@@ -835,10 +836,52 @@ bool UGPUInstancedLineComponent::UpdatePoint(int32 LineId, int32 PointId, const ...@@ -835,10 +836,52 @@ bool UGPUInstancedLineComponent::UpdatePoint(int32 LineId, int32 PointId, const
return true; return true;
} }
bool UGPUInstancedLineComponent::UpdatePoints(int32 LineId, int32 StartingPointId, const TArray<FVector>& Points) // todo test this not sure if it actually works
bool UGPUInstancedLineComponent::UpdatePoints(int32 LineId, int32 StartingPointId, TArray<FVector>& Points)
{
TRACE_CPUPROFILER_EVENT_SCOPE(TEXT("UGPUInstancedLineComponent::UpdatePoints"))
const GPULineArray& Line = LineMap[LineId];
if (Line.Num() < Points.Num() || StartingPointId + Points.Num() > Line.Num())
{ {
return false; return false;
} }
if(Line.Num() == Points.Num() && StartingPointId == 0)
{
return UpdateLine(LineId, Points);
}
// Should check for validity
const GPULineIndices& FirstPointIndices = LineMap[LineId][StartingPointId];
TArray<FVector4>* TextureData = new TArray<FVector4>(MoveTemp(Points));
if(StartingPointId == 0)
{
(*TextureData)[0].W = 0;
}
if (StartingPointId + Points.Num() == Line.Num())
{
TextureData->Last().W = -1;
}
const int32 StartTextureIndex = Line[StartingPointId].Value;
const FIntPoint StartIndex(StartTextureIndex % TextureWidth, StartTextureIndex / TextureWidth);
FMemory::Memcpy(LinearLineData.GetData() + StartTextureIndex, TextureData->GetData(), TextureData->Num() * sizeof(FVector4));
int32 NumberOfRegions = 0;
const FUpdateTextureRegion2D* Regions = CalculateTextureRegions(StartIndex, TextureData->Num(), NumberOfRegions);
PositionTexture->UpdateTextureRegions(0, NumberOfRegions, Regions, TextureWidth * sizeof(FVector4), sizeof(FVector4), (uint8*)TextureData->GetData(),
[](auto InTextureData, auto InRegions)
{
delete InTextureData;
delete InRegions;
});
return true;
}
bool UGPUInstancedLineComponent::RemoveLine(int32 LineId) bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
{ {
...@@ -848,11 +891,24 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId) ...@@ -848,11 +891,24 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
const int32 LineLength = Line.Num(); const int32 LineLength = Line.Num();
const int32 LineTextureIndex = Line[0].Value; const int32 LineTextureIndex = Line[0].Value;
// Remove the instances first: // Because ISM are so great, they reshuffle id's on removal....
// This means we can't just remove consecutive ids, but need to actually re-calculate them EVERY SINGLE TIME
// As instances of a line aren't guaranteed to be in order, collect and sort the indices first, then start top down.
//
TArray<int32> InstancesToRemove;
InstancesToRemove.Reserve(Line.Num());
for(int32 PointIndex = 0; PointIndex < Line.Num() - 1; PointIndex++) for(int32 PointIndex = 0; PointIndex < Line.Num() - 1; PointIndex++)
{ {
RemoveInstance(Line[PointIndex].Key); InstancesToRemove.Add(Line[PointIndex].Key);
}
InstancesToRemove.Sort();
for (int32 Index = 0; Index < InstancesToRemove.Num(); Index++)
{
RemoveInstance(InstancesToRemove[InstancesToRemove.Num() - 1 - Index]);
} }
// Remove linear data: // Remove linear data:
LinearLineData.RemoveAt(LineTextureIndex, LineLength); LinearLineData.RemoveAt(LineTextureIndex, LineLength);
// Remove line from map, this invalidates above Line reference. // Remove line from map, this invalidates above Line reference.
...@@ -862,9 +918,23 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId) ...@@ -862,9 +918,23 @@ bool UGPUInstancedLineComponent::RemoveLine(int32 LineId)
for (TPair<int32, GPULineArray>& Pair : LineMap) for (TPair<int32, GPULineArray>& Pair : LineMap)
{ {
GPULineArray& LineArray = Pair.Value; GPULineArray& LineArray = Pair.Value;
if (LineArray[0].Value >= LineTextureIndex)
{
for (int32 i = 0; i < LineArray.Num(); ++i) for (int32 i = 0; i < LineArray.Num(); ++i)
{
if (LineArray[i].Key >= InstancesToRemove[0])
{
// Apparently unreal also shuffles the instance indices, this might bite us later on
// This is insanely slow:
for(int32 Index = InstancesToRemove.Num(); Index > 0; --Index)
{
if (LineArray[i].Key >= InstancesToRemove[Index - 1])
{
LineArray[i].Key -= Index;
}
}
}
if (LineArray[0].Value >= LineTextureIndex)
{ {
LineArray[i].Value -= LineLength; LineArray[i].Value -= LineLength;
SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false); SetCustomDataValue(LineArray[i].Key, 4, LineArray[i].Value, false);
......
...@@ -227,7 +227,7 @@ public: ...@@ -227,7 +227,7 @@ public:
// todo // todo
UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent") UFUNCTION(BlueprintCallable, Category = "Components|InstancedLineComponent")
bool UpdatePoints(int32 LineId, int32 StartingPointId, const TArray<FVector>& Points); bool UpdatePoints(int32 LineId, int32 StartingPointId, TArray<FVector>& Points);
// Removal Functions // Removal Functions
// todo // todo
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment