From 492eab0a00f40cbef2dc54b976ab0c8824ccd3ef Mon Sep 17 00:00:00 2001 From: Timon Roemer <t.roemer@vis.rwth-aachen.de> Date: Mon, 22 Jul 2024 18:15:03 +0200 Subject: [PATCH] optimizes MagicWand by Paralellizing --- Content/MagicWandMap.umap | Bin 43681 -> 43795 bytes Source/MetaCastBachelor/MagicWand.cpp | 540 ++++++++++-------- Source/MetaCastBachelor/MagicWand.h | 62 +- Source/MetaCastBachelor/MarchingCubes.compute | 449 +++++++++++++++ Source/MetaCastBachelor/MetaCastBaseline.cpp | 18 +- Source/MetaCastBachelor/MetaCastBaseline.h | 1 + Source/MetaCastBachelor/PointCloud.cpp | 2 +- 7 files changed, 802 insertions(+), 270 deletions(-) create mode 100644 Source/MetaCastBachelor/MarchingCubes.compute diff --git a/Content/MagicWandMap.umap b/Content/MagicWandMap.umap index bd7492ae734fcd1e7e27825d4ae8845abe574fec..5abed2d8bc29ddf32c4cf888d4f03b16036d6e0a 100644 GIT binary patch delta 14199 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 I<lI#z07(s*SO5S3 delta 13457 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 JlkcxG0RZ%CbU*+A diff --git a/Source/MetaCastBachelor/MagicWand.cpp b/Source/MetaCastBachelor/MagicWand.cpp index 4b2f64b..cda7616 100644 --- a/Source/MetaCastBachelor/MagicWand.cpp +++ b/Source/MetaCastBachelor/MagicWand.cpp @@ -1,26 +1,25 @@ #include "MagicWand.h" - -#include "KdtreeBPLibrary.h" #include "Utilities.h" #include "Generators/MarchingCubes.h" +// INITIALIZATION + UMagicWand::UMagicWand() : World(nullptr) { // Create the procedural mesh component ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh")); - SelectedClusterIndices.Reserve(100000); } void UMagicWand::BeginPlay() { Super::BeginPlay(); - World = GetWorld(); - - if (!World) { - UE_LOG(LogTemp, Warning, TEXT("Invalid world provided.")); - } + InitReferences(); + InitProceduralMesh(); +} +void UMagicWand::InitProceduralMesh() const +{ ProceduralMesh->AttachToComponent(MyPointCloud->PointCloudVisualizer, FAttachmentTransformRules::SnapToTargetIncludingScale); ProceduralMesh->SetMaterial(0, SelectionVolumeMat); ProceduralMesh->SetMaterial(1, SelectionVolumeMat); @@ -31,252 +30,30 @@ void UMagicWand::BeginPlay() ProceduralMesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); ProceduralMesh->SetMobility(EComponentMobility::Movable); ProceduralMesh->SetVisibility(true); - -} - -void UMagicWand::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) -{ - Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - - AccumulatedTime += DeltaTime; - - ProceduralMesh->SetVisibility(Select); } -void UMagicWand::EraseParticles(const FVector& InputPosition) +void UMagicWand::InitReferences() { - -} - -void UMagicWand::HandleMetaSelectReleased(const FInputActionInstance& Instance) -{ - Super::HandleMetaSelectReleased(Instance); - - //ProceduralMesh->ClearAllMeshSections(); - //ProceduralMesh->SetVisibility(false); - - - AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]() + if (!MyPointCloud || !MyPointCloud->MyDensityField) { + UE_LOG(LogTemp, Error, TEXT("Invalid Point Cloud or DensityField provided!")); + }else { - MyPointCloud->ColorPointsInVoxels(FloodedIndices); - }); -} - -void UMagicWand::HandleMetaSelectPressed(const FInputActionInstance& Instance) -{ - Super::HandleMetaSelectPressed(Instance); - - InitMagicWandSelection(); -} - -void UMagicWand::HandleMetaEraseReleased(const FInputActionInstance& Instance) -{ - Super::HandleMetaEraseReleased(Instance); - - //deselect all particles - for (int32 i = 0; i < MyPointCloud->SelectionFlags.Num(); ++i) - { - MyPointCloud->SelectionFlags[i] = false; + MyDensityField = MyPointCloud->MyDensityField; } -} - -void UMagicWand::InitMagicWandSelection() -{ - const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation(); - MyDensityField = MyPointCloud->MyDensityField; - - // Convert the world position of the selection object to the local position relative to the point cloud - ProceduralMesh->ClearAllMeshSections(); + World = GetWorld(); - AbortMarchingCubes = true; - //AccumulatedTime = 0.0f; -} - -void UMagicWand::SelectParticles(const FVector& InputPosition) -{ - if (AccumulatedTime >= 1 / EvaluationsPerSecond) - { - AccumulatedTime = -10000; - - UE_LOG(LogTemp, Warning, TEXT("Input recognized!")); - AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]() - { - const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation(); - const FVector SelectionLocalPosition = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition); - - PerformMagicWandSelection(SelectionLocalPosition); - - //UE_LOG(LogTemp, Warning, TEXT("Calculations done!")); - }); - + if (!World) { + UE_LOG(LogTemp, Error, TEXT("Invalid world provided.")); } } -void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition) +void UMagicWand::EraseParticles(const FVector& InputPosition) { - if (MyPointCloud->SelectionFlags.Num() != MyPointCloud->PositionVectors.Num()) - { - UE_LOG(LogTemp, Warning, TEXT("PerformMagicWandSelection: Positions and SelectionFlags array sizes do not match.")); - return; - } - - UE_LOG(LogTemp, Warning, TEXT("Starting Selection!")); - - //UE_LOG(LogTemp, Warning, TEXT("Looking for Seed Index:")); - // Find the closest point to the input position as the seed - const int32 InputVoxelIndex = MyDensityField->WorldPositionToIndex(InputPosition); - TArray<int32> Neighbors = MyDensityField->IndexToVoxelNeighbors(InputVoxelIndex); - Neighbors.Add(InputVoxelIndex); - int32 SeedIndex = INDEX_NONE; - float MinDistance = FLT_MAX; - - - for(int NeighborDistance = 0; NeighborDistance < 3; ++NeighborDistance) - { - const int NumNeighbors = Neighbors.Num(); - - for (int i = 0; i < NumNeighbors; ++i) - { - const int CurrentNeighborIndex = Neighbors[i]; - TArray<int32> NeighborsOfNeighbors = MyDensityField->IndexToVoxelNeighbors(CurrentNeighborIndex); - - for (int CurrentNeighborOfNeighborIndex : NeighborsOfNeighbors) - { - if (!Neighbors.Contains(CurrentNeighborOfNeighborIndex)) - { - Neighbors.Add(CurrentNeighborOfNeighborIndex); - } - } - } - } - - for (const int CurrentNeighborIndex : Neighbors) - { - TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentNeighborIndex); - - for(const int32 CurrentIndex : PointIndices) - { - FVector CurrentPosition = MyDensityField->IndexToVoxelPosition(CurrentIndex); - const float Distance = FVector::Dist(InputPosition, CurrentPosition); - if (Distance < MinDistance) - { - MinDistance = Distance; - SeedIndex = CurrentIndex; - } - } - } - - if (SeedIndex != INDEX_NONE) - { - //const FVector WorldPos = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(MyPointCloud->PositionVectors[SeedIndex]); - //DrawDebugSphere(World, WorldPos, 0.1f, 20, FColor::Green, false, 1, 0, 1.0f); - - //Expand selection from the seed - ExpandSelection(SeedIndex); - }else - { - AccumulatedTime = 0; - } } -void UMagicWand::ExpandSelection(const int32 SeedIndex) -{ - UE_LOG(LogTemp, Warning, TEXT("Expanding!")); - TQueue<int32> ToProcess; - ToProcess.Enqueue(SeedIndex); - - SelectedClusterIndices.Add(SeedIndex); - MyPointCloud->SelectionFlags[SeedIndex] = true; - - const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold; - TArray<int> Indices; - TArray<FVector> Data; - - while (!ToProcess.IsEmpty()) - { - int32 CurrentQueuePointIndex; - ToProcess.Dequeue(CurrentQueuePointIndex); - - const FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex]; - - Indices.Empty(); - Data.Empty(); - - UKdtreeBPLibrary::CollectFromKdtree(MyPointCloud->MyKdTree, CurrentQueuePointPosition, MyPointCloud->InfluenceRadius, Indices, Data); - - for(int i = 0; i < Indices.Num(); ++i) - { - const int CurrentPointComparisonIndex = Indices[i]; - - if(MyPointCloud->SelectionFlags[CurrentPointComparisonIndex]) - { - continue; - } - - ToProcess.Enqueue(CurrentPointComparisonIndex); - MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true; - } - - /* - const int32 StartX = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.X - ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X)); - const int32 EndX = FMath::Min(MyDensityField->GetXNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.X + ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X)); - const int32 StartY = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Y - ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y)); - const int32 EndY = FMath::Min(MyDensityField->GetYNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Y + ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y)); - const int32 StartZ = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Z - ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z)); - const int32 EndZ = FMath::Min(MyDensityField->GetZNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Z + ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z)); - - - UE_LOG(LogTemp, Warning, TEXT("CurrentQueuePointPosition: %s"), *CurrentQueuePointPosition.ToString()); - UE_LOG(LogTemp, Warning, TEXT("StartX: %d"), StartX); - UE_LOG(LogTemp, Warning, TEXT("EndX: %d"), EndX); - UE_LOG(LogTemp, Warning, TEXT("StartY: %d"), StartY); - UE_LOG(LogTemp, Warning, TEXT("EndY: %d"), EndY); - UE_LOG(LogTemp, Warning, TEXT("StartZ: %d"), StartZ); - UE_LOG(LogTemp, Warning, TEXT("EndZ: %d"), EndZ); - - for (int32 Z = StartZ; Z <= EndZ; ++Z) - { - for (int32 Y = StartY; Y <= EndY; ++Y) - { - for (int32 X = StartX; X <= EndX; ++X) - { - const int32 CurrentVoxelComparisonIndex = MyDensityField->GridPositionToIndex(X, Y, Z); - - /* - if(!MyDensityField->IsValidIndex(CurrentVoxelComparisonIndex)) - { - continue; - } - - TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentVoxelComparisonIndex); - - for(const int32 CurrentPointComparisonIndex : PointIndices) - { - if(MyPointCloud->SelectionFlags[CurrentPointComparisonIndex]) - { - continue; - } - - FVector CurrentComparisonPosition = MyPointCloud->PositionVectors[CurrentPointComparisonIndex]; - const double SquaredDistance = FVector::DistSquared(CurrentQueuePointPosition, CurrentComparisonPosition); - - if (SquaredDistance <= SquaredProximityThreshold) - { - ToProcess.Enqueue(CurrentPointComparisonIndex); - //SelectedClusterIndices.Add(CurrentPointComparisonIndex); - MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true; - } - } - } - } - }*/ - } - - UE_LOG(LogTemp, Warning, TEXT("Calculations done!")); - AccumulatedTime = 0; -} +// VISUALIZATION void UMagicWand::GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const { @@ -405,8 +182,289 @@ void UMagicWand::GenerateVoxelMeshSmooth(const TArray<int32> Voxels) FScopeLock MeshLock(&ProceduralMeshGuard); ProceduralMesh->CreateMeshSection(0, Vertices, Indices, Normals, TArray<FVector2D>(), VertexColors, TArray<FProcMeshTangent>(), false); ProceduralMesh->SetVisibility(true); - AccumulatedTime = 0.0f; + AccumulatedTime.Store(0); IsMarchingCubesRunning = false; }); }); +} + +// INPUT HANDLING + +void UMagicWand::HandleMetaSelectReleased(const FInputActionInstance& Instance) +{ + Super::HandleMetaSelectReleased(Instance); + + const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation(); + const FVector SelectionLocalPosition = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition); + + ProximityThreshold = FMath::Clamp(FVector::Dist(SelectionStartPosition, SelectionLocalPosition) / 10, 0.1, 10); + + InitMagicWandSelection(); + + AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this, &SelectionLocalPosition]() + { + PerformMagicWandSelection(SelectionStartPosition); + }); +} + +void UMagicWand::HandleMetaSelectPressed(const FInputActionInstance& Instance) +{ + Super::HandleMetaSelectPressed(Instance); + + const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation(); + SelectionStartPosition = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition); +} + +void UMagicWand::HandleMetaEraseReleased(const FInputActionInstance& Instance) +{ + Super::HandleMetaEraseReleased(Instance); + + FScopeLock Lock(&ThreadNumberLock); + AbortMagicWand.Store(true); + + //deselect all particles + for (int32 i = 0; i < MyPointCloud->SelectionFlags.Num(); ++i) + { + MyPointCloud->SelectionFlags[i] = false; + } +} + +// MAGIC WAND SELECTION + +void UMagicWand::InitMagicWandSelection() +{ + ProceduralMesh->ClearAllMeshSections(); + AbortMarchingCubes = true; + if(AccumulatedTime.Load() >= 0) AccumulatedTime.Store(1 / EvaluationsPerSecond); + AbortMagicWand.Store(false); +} + +void UMagicWand::PerformMagicWandSelection(const FVector& InputPosition) +{ + if (MyPointCloud->SelectionFlags.Num() != MyPointCloud->PositionVectors.Num()) + { + UE_LOG(LogTemp, Error, TEXT("PerformMagicWandSelection: Positions and SelectionFlags array sizes do not match.")); + return; + } + + //UE_LOG(LogTemp, Warning, TEXT("Starting MagicWand Selection!")); + + // Find the closest point to the input position as the seed + int32 SeedIndex; + const int32 InputVoxelIndex = MyDensityField->WorldPositionToIndex(InputPosition); + FindSeedIndex(InputPosition, InputVoxelIndex, SeedIndex); + + if (SeedIndex != INDEX_NONE) + { + ExpandSelectionFromPointIndex(SeedIndex); + }else + { + AccumulatedTime.Store( 0); + } +} + +void UMagicWand::FindSeedIndex(const FVector& InputPosition, const int32 InputVoxelIndex, int32& SeedIndex) const +{ + TArray<int32> Neighbors = MyDensityField->IndexToVoxelNeighbors(InputVoxelIndex); + Neighbors.Add(InputVoxelIndex); + + SeedIndex = INDEX_NONE; + float MinDistance = FLT_MAX; + + for(int NeighborDistance = 0; NeighborDistance < 4; ++NeighborDistance) + { + const int NumNeighbors = Neighbors.Num(); + + for (int i = 0; i < NumNeighbors; ++i) + { + const int CurrentNeighborIndex = Neighbors[i]; + TArray<int32> NeighborsOfNeighbors = MyDensityField->IndexToVoxelNeighbors(CurrentNeighborIndex); + + for (int CurrentNeighborOfNeighborIndex : NeighborsOfNeighbors) + { + if (!Neighbors.Contains(CurrentNeighborOfNeighborIndex)) + { + Neighbors.Add(CurrentNeighborOfNeighborIndex); + } + } + } + } + + + for (const int CurrentNeighborIndex : Neighbors) + { + TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentNeighborIndex); + + for(const int32 CurrentIndex : PointIndices) + { + FVector CurrentPosition = MyDensityField->IndexToVoxelPosition(CurrentIndex); + const float Distance = FVector::Dist(InputPosition, CurrentPosition); + if (Distance < MinDistance) + { + MinDistance = Distance; + SeedIndex = CurrentIndex; + } + } + } +} + +void UMagicWand::ExpandSelectionFromPointIndex(const int32 SeedIndex) +{ + { + FScopeLock Lock(&ThreadNumberLock); + NumberThreads.Increment(); + } + + TQueue<int32>* ProcessQueue = new TQueue<int32>{}; + ProcessQueue->Enqueue(SeedIndex); + MyPointCloud->SelectionFlags[SeedIndex] = true; + + const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold; + int NumberToProcess = 0; + + while (!ProcessQueue->IsEmpty() && !AbortMagicWand.Load()) + { + if(NumberToProcess > 1000 && NumberThreads.GetValue() < MaxThreadCount) CreateNewExpansionThread(ProcessQueue, NumberToProcess); + + int32 CurrentQueuePointIndex; + ProcessQueue->Dequeue(CurrentQueuePointIndex); + const FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex]; + + ExpandThroughNeighborsInRange(ProcessQueue, SquaredProximityThreshold, NumberToProcess, CurrentQueuePointPosition); + NumberToProcess--; + } + + AbortSelection(); +} + +void UMagicWand::ExpandSelectionFromPointIndexQueue(TQueue<int32>* ProcessQueue) +{ + { + FScopeLock Lock(&ThreadNumberLock); + NumberThreads.Increment(); + } + //UE_LOG(LogTemp, Warning, TEXT("Opened New Thread! Number of Threads now: %d"), NumberThreads.GetValue()); + const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold; + int NumberToProcess = 0; + + while (!ProcessQueue->IsEmpty() && !AbortMagicWand.Load()) + { + if(NumberToProcess > 1000 && NumberThreads.GetValue() < MaxThreadCount) CreateNewExpansionThread(ProcessQueue, NumberToProcess); + + int32 CurrentQueuePointIndex; + ProcessQueue->Dequeue(CurrentQueuePointIndex); + const FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex]; + + ExpandThroughNeighborsInRange(ProcessQueue, SquaredProximityThreshold, NumberToProcess, CurrentQueuePointPosition); + NumberToProcess--; + } + + AbortSelection(); +} + +void UMagicWand::ExpandThroughNeighborsInRange(TQueue<int32>* ProcessQueue, const float SquaredProximityThreshold, int& NumberToProcess, const FVector& CurrentQueuePointPosition) const +{ + const int32 StartX = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.X - ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X)); + const int32 EndX = FMath::Min(MyDensityField->GetXNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.X + ProximityThreshold - MyPointCloud->MinBounds.X) / MyDensityField->GetStep().X)); + const int32 StartY = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Y - ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y)); + const int32 EndY = FMath::Min(MyDensityField->GetYNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Y + ProximityThreshold - MyPointCloud->MinBounds.Y) / MyDensityField->GetStep().Y)); + const int32 StartZ = FMath::Max(0, FMath::FloorToInt((CurrentQueuePointPosition.Z - ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z)); + const int32 EndZ = FMath::Min(MyDensityField->GetZNum() - 1, FMath::FloorToInt((CurrentQueuePointPosition.Z + ProximityThreshold - MyPointCloud->MinBounds.Z) / MyDensityField->GetStep().Z)); + + for (int32 Z = StartZ; Z <= EndZ; ++Z) + { + for (int32 Y = StartY; Y <= EndY; ++Y) + { + for (int32 X = StartX; X <= EndX; ++X) + { + if(AbortMagicWand.Load()) return; + const int32 CurrentVoxelComparisonIndex = MyDensityField->GridPositionToIndex(X, Y, Z); + + if(!MyDensityField->IsValidIndex(CurrentVoxelComparisonIndex)) + { + continue; + } + + TArray<int32> PointIndices = MyDensityField->VoxelPointLookupTable->GetPointsInVoxel(CurrentVoxelComparisonIndex); + + for(const int32 CurrentPointComparisonIndex : PointIndices) + { + if(MyPointCloud->SelectionFlags[CurrentPointComparisonIndex]) + { + continue; + } + + FVector CurrentComparisonPosition = MyPointCloud->PositionVectors[CurrentPointComparisonIndex]; + const double SquaredDistance = FVector::DistSquared(CurrentQueuePointPosition, CurrentComparisonPosition); + + if (SquaredDistance <= SquaredProximityThreshold) + { + ProcessQueue->Enqueue(CurrentPointComparisonIndex); + NumberToProcess++; + + if(AbortMagicWand.Load()) return; + + MyPointCloud->SelectionFlags[CurrentPointComparisonIndex] = true; + } + } + } + } + } +} + +void UMagicWand::AbortSelection() +{ + NumberThreads.Decrement(); + + //UE_LOG(LogTemp, Warning, TEXT("Thread Closed! Number of Threads now: %d"), NumberThreads.GetValue()); + if(NumberThreads.GetValue() == 0) + { + AccumulatedTime.Store(0); + //AbortMagicWand.Store(false); + //UE_LOG(LogTemp, Warning, TEXT("Aborted!")); + }else if(NumberThreads.GetValue() < 0) + { + UE_LOG(LogTemp, Error, TEXT("More Threads closed than opened!")); + } +} + +void UMagicWand::CreateNewExpansionThread(TQueue<int32>* ProcessQueue, int& NumberToProcess) +{ + TQueue<int32>* TempQueue = new TQueue<int32>{}; + const int NumberRemove = NumberToProcess / 2; + + for(int i = 0; i < NumberRemove; ++i) + { + int32 CurrentQueuePointIndex; + ProcessQueue->Dequeue(CurrentQueuePointIndex); + NumberToProcess--; + TempQueue->Enqueue(CurrentQueuePointIndex); + } + + AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this, TempQueue]() + { + ExpandSelectionFromPointIndexQueue(TempQueue); + }); +} + +// TICK + +void UMagicWand::TickComponent(const float DeltaTime, const ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) +{ + Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + + /* + AccumulatedTime.Store(AccumulatedTime.Load() + DeltaTime); + ProceduralMesh->SetVisibility(Select);*/ +} + +void UMagicWand::SelectParticles(const FVector& InputPosition) +{ + if (AccumulatedTime.Load() >= 1 / EvaluationsPerSecond) + { + AccumulatedTime.Store(FLT_MIN); + } + + const FVector SelectionWorldPosition = SelectionObject->GetComponentLocation(); + DrawDebugLine(World, SelectionWorldPosition, MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(SelectionStartPosition), FColor::Red, false, 0, 0, 0.1f); } \ No newline at end of file diff --git a/Source/MetaCastBachelor/MagicWand.h b/Source/MetaCastBachelor/MagicWand.h index e84de2e..0037e3b 100644 --- a/Source/MetaCastBachelor/MagicWand.h +++ b/Source/MetaCastBachelor/MagicWand.h @@ -1,59 +1,79 @@ - #pragma once #include "CoreMinimal.h" #include "ProceduralMeshComponent.h" #include "MetaCastBaseline.h" #include "Generators/MarchingCubes.h" +#include "Templates/Atomic.h" #include "MagicWand.generated.h" UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class UMagicWand : public UMetaCastBaseline { GENERATED_BODY() - + + // INTERNAL + + TAtomic<bool> AbortMagicWand = false; FDensityField* MyDensityField; - UPROPERTY() - UWorld* World; bool IsMarchingCubesRunning = false; bool AbortMarchingCubes = false; - - // Critical section to protect shared variables + FThreadSafeCounter NumberThreads = 0; mutable FCriticalSection ProceduralMeshGuard; - + mutable FCriticalSection ThreadNumberLock; UPROPERTY() UProceduralMeshComponent* ProceduralMesh; - UPROPERTY(EditAnywhere) - UMaterialInterface* SelectionVolumeMat; - TArray<int32> FloodedIndices; + UPROPERTY() + UWorld* World; + TAtomic<float> AccumulatedTime = 0.0; + FVector SelectionStartPosition; + + // USER EXPORTED + UPROPERTY(EditAnywhere) float MarchingCubeSize = 0; UPROPERTY(EditAnywhere) int EvaluationsPerSecond = 10; UPROPERTY(EditAnywhere) - float AccumulatedTime = 0.0; - UPROPERTY(EditAnywhere) float ProximityThreshold = 0.1f; - TArray<int32> SelectedClusterIndices; - + UPROPERTY(EditAnywhere) + UMaterialInterface* SelectionVolumeMat; + UPROPERTY(EditAnywhere) + int MaxThreadCount = 100; public: - UMagicWand(); + // INITIALIZATION + UMagicWand(); virtual void BeginPlay() override; - - virtual void SelectParticles(const FVector& InputPosition) override; - virtual void EraseParticles(const FVector& InputPosition) override; + void InitReferences(); + void InitProceduralMesh() const; + // INPUT HANDLING + virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override; virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override; virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance) override; - void InitMagicWandSelection(); + virtual void EraseParticles(const FVector& InputPosition) override; + // VISUALIZATION + void GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const; void GenerateVoxelMeshSmooth(const TArray<int32> Voxels); - virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + // MAGIC WAND SELECTION + + void InitMagicWandSelection(); + void FindSeedIndex(const FVector& InputPosition, int32 InputVoxelIndex, int32& SeedIndex) const; void PerformMagicWandSelection(const FVector& InputPosition); - void ExpandSelection(int32 SeedIndex); + void ExpandSelectionFromPointIndex(int32 SeedIndex); + void ExpandSelectionFromPointIndexQueue(TQueue<int32>* ProcessQueue); + void ExpandThroughNeighborsInRange(TQueue<int32>* ProcessQueue, const float SquaredProximityThreshold, int& NumberToProcess, const FVector& CurrentQueuePointPosition) const; + void AbortSelection(); + void CreateNewExpansionThread(TQueue<int32>* ProcessQueue, int& NumberToProcess); + + // TICK + + virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; + virtual void SelectParticles(const FVector& InputPosition) override; }; \ No newline at end of file diff --git a/Source/MetaCastBachelor/MarchingCubes.compute b/Source/MetaCastBachelor/MarchingCubes.compute new file mode 100644 index 0000000..01628e5 --- /dev/null +++ b/Source/MetaCastBachelor/MarchingCubes.compute @@ -0,0 +1,449 @@ +//The following code is modified from "unity-marching-cubes-gpu" by Pavel Kouřil. Original at: "https://github.com/pavelkouril/unity-marching-cubes-gpu" + +/** + * Lookup tables and algorithm taken from "Polygonising a scalar field" by Paul Bourke + * + * Original at: http://paulbourke.net/geometry/polygonise/ + */ + +#pragma kernel MarchingCubes +Texture3D<float4> _posTexture; +Texture3D<float4> _densityTexture; +Texture3D<float4> _mcFlagTexture; +float _isoLevel; +int _gridSize; + +struct Vertex +{ + float3 vPosition; + float3 vNormal; +}; + +struct Triangle +{ + Vertex v[3]; +}; + +AppendStructuredBuffer<Triangle> triangleRW; + +SamplerState myLinearClampSampler; + +static const int edgeTable[256] = { + 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, + 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, + 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, + 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, + 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, + 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, + 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, + 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, + 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, + 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, + 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, + 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, + 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, + 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, + 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , + 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, + 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, + 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, + 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, + 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, + 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, + 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, + 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, + 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, + 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, + 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, + 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, + 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, + 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, + 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, + 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, + 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 }; + +static const int triTable[256][16] = +{ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, +{ 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, +{ 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, +{ 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, +{ 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, +{ 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, +{ 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, +{ 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, +{ 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, +{ 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, +{ 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, +{ 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, +{ 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, +{ 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, +{ 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, +{ 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, +{ 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, +{ 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, +{ 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, +{ 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, +{ 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, +{ 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, +{ 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, +{ 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, +{ 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, +{ 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, +{ 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, +{ 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 }, +{ 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, +{ 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 }, +{ 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, +{ 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, +{ 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 }, +{ 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, +{ 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 }, +{ 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, +{ 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, +{ 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, +{ 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, +{ 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, +{ 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, +{ 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 }, +{ 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, +{ 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, +{ 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, +{ 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, +{ 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, +{ 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, +{ 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, +{ 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, +{ 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, +{ 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, +{ 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, +{ 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, +{ 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, +{ 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, +{ 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, +{ 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, +{ 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, +{ 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, +{ 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, +{ 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, +{ 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, +{ 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, +{ 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, +{ 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 }, +{ 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, +{ 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, +{ 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, +{ 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, +{ 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, +{ 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 }, +{ 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 }, +{ 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, +{ 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, +{ 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, +{ 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, +{ 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, +{ 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, +{ 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, +{ 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, +{ 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 }, +{ 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, +{ 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, +{ 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, +{ 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, +{ 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, +{ 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 }, +{ 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, +{ 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 }, +{ 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, +{ 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, +{ 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, +{ 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, +{ 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, +{ 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 }, +{ 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, +{ 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, +{ 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, +{ 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, +{ 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, +{ 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 }, +{ 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, +{ 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 }, +{ 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, +{ 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, +{ 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, +{ 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, +{ 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, +{ 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 }, +{ 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, +{ 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 }, +{ 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, +{ 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, +{ 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, +{ 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } }; + +float SampleData(int3 pos) { // read the val data from the texture + return _densityTexture.Load(int4(pos, 0)).x; +} + +float3 SamplePosData(int3 pos) { // read the pos data from the texture + return float3(_posTexture.Load(int4(pos, 0)).x, _posTexture.Load(int4(pos, 0)).y, _posTexture.Load(int4(pos, 0)).z); +} +float SampleFlagData(int3 pos) { // read the pos data from the texture + return _mcFlagTexture.Load(int4(pos, 0)).x; +} +float SampleLinear(float3 p) +{ + // need to mitigate the offset in p[x], so +float3(0.5) to be in [0;1] range + return _densityTexture.SampleLevel(myLinearClampSampler, p + float3(0.5, 0.5, 0.5), 0).x; +} + +float3 VertexInterp(float3 p1, float3 p2, float valp1, float valp2) +{ + return lerp(p1, p2, (_isoLevel - valp1) / (valp2 - valp1)); +} + +float3 CalculateGradient(float3 p) +{ + float ratio = 1.0 / (_gridSize ); + + return float3( + SampleLinear(p - float3(1.0, 0.0, 0.0) * ratio) + - SampleLinear(p + float3(1.0, 0.0, 0.0) * ratio), + + SampleLinear(p - float3(0.0, 1.0, 0.0) * ratio) + - SampleLinear(p + float3(0.0, 1.0, 0.0) * ratio), + + SampleLinear(p - float3(0.0, 0.0, 1.0) * ratio) + - SampleLinear(p + float3(0.0, 0.0, 1.0) * ratio) + ); +} + +[numthreads(8, 8, 8)] +void MarchingCubes(uint3 threadId : SV_DispatchThreadID) +{ + if (SampleFlagData(threadId) == 0) + return; + + float3 p[8] = { + SamplePosData(threadId + int3(0, 0, 1)), + SamplePosData(threadId + int3(1, 0, 1)), + SamplePosData(threadId + int3(1, 0, 0)), + SamplePosData(threadId + int3(0, 0, 0)), + SamplePosData(threadId + int3(0, 1, 1)), + SamplePosData(threadId + int3(1, 1, 1)), + SamplePosData(threadId + int3(1, 1, 0)), + SamplePosData(threadId + int3(0, 1, 0)) + }; + + float val[8] = { + SampleData(threadId + int3(0, 0, 1)), + SampleData(threadId + int3(1, 0, 1)), + SampleData(threadId + int3(1, 0, 0)), + SampleData(threadId + int3(0, 0, 0)), + SampleData(threadId + int3(0, 1, 1)), + SampleData(threadId + int3(1, 1, 1)), + SampleData(threadId + int3(1, 1, 0)), + SampleData(threadId + int3(0, 1, 0)) + }; + + int cubeIndex = 0; + if (val[0] < _isoLevel) cubeIndex |= 1; + if (val[1] < _isoLevel) cubeIndex |= 2; + if (val[2] < _isoLevel) cubeIndex |= 4; + if (val[3] < _isoLevel) cubeIndex |= 8; + if (val[4] < _isoLevel) cubeIndex |= 16; + if (val[5] < _isoLevel) cubeIndex |= 32; + if (val[6] < _isoLevel) cubeIndex |= 64; + if (val[7] < _isoLevel) cubeIndex |= 128; + + float3 vertlist[12]; + + if (edgeTable[cubeIndex] != 0) + { + if (edgeTable[cubeIndex] & 1) + vertlist[0] = VertexInterp(p[0], p[1], val[0], val[1]); + if (edgeTable[cubeIndex] & 2) + vertlist[1] = VertexInterp(p[1], p[2], val[1], val[2]); + if (edgeTable[cubeIndex] & 4) + vertlist[2] = VertexInterp(p[2], p[3], val[2], val[3]); + if (edgeTable[cubeIndex] & 8) + vertlist[3] = VertexInterp(p[3], p[0], val[3], val[0]); + if (edgeTable[cubeIndex] & 16) + vertlist[4] = VertexInterp(p[4], p[5], val[4], val[5]); + if (edgeTable[cubeIndex] & 32) + vertlist[5] = VertexInterp(p[5], p[6], val[5], val[6]); + if (edgeTable[cubeIndex] & 64) + vertlist[6] = VertexInterp(p[6], p[7], val[6], val[7]); + if (edgeTable[cubeIndex] & 128) + vertlist[7] = VertexInterp(p[7], p[4], val[7], val[4]); + if (edgeTable[cubeIndex] & 256) + vertlist[8] = VertexInterp(p[0], p[4], val[0], val[4]); + if (edgeTable[cubeIndex] & 512) + vertlist[9] = VertexInterp(p[1], p[5], val[1], val[5]); + if (edgeTable[cubeIndex] & 1024) + vertlist[10] = VertexInterp(p[2], p[6], val[2], val[6]); + if (edgeTable[cubeIndex] & 2048) + vertlist[11] = VertexInterp(p[3], p[7], val[3], val[7]); + + for (int i = 0; triTable[cubeIndex][i] != -1; i += 3) { + Triangle t; + + Vertex v0; + Vertex v1; + Vertex v2; + + v0.vPosition = vertlist[triTable[cubeIndex][i]]; + v1.vPosition = vertlist[triTable[cubeIndex][i + 1]]; + v2.vPosition = vertlist[triTable[cubeIndex][i + 2]]; + + v0.vNormal = normalize(CalculateGradient(v0.vPosition)); + v1.vNormal = normalize(CalculateGradient(v1.vPosition)); + v2.vNormal = normalize(CalculateGradient(v2.vPosition)); + + t.v[0] = v0; + t.v[1] = v1; + t.v[2] = v2; + + triangleRW.Append(t); + } + } +} \ No newline at end of file diff --git a/Source/MetaCastBachelor/MetaCastBaseline.cpp b/Source/MetaCastBachelor/MetaCastBaseline.cpp index f6bd224..6485e9d 100644 --- a/Source/MetaCastBachelor/MetaCastBaseline.cpp +++ b/Source/MetaCastBachelor/MetaCastBaseline.cpp @@ -10,6 +10,16 @@ UMetaCastBaseline::UMetaCastBaseline() : PrimaryComponentTick.bCanEverTick = true; } +void UMetaCastBaseline::InitLeftHand() +{ + //check if left hand is assigned otherwise assign it to self + if(!LeftHandComponent) + { + UE_LOG(LogTemp, Warning, TEXT("Left Hand not assigned. Please assign in Blueprint => Defaulting to self")); + LeftHandComponent = this; + } +} + // Called when the game starts void UMetaCastBaseline::BeginPlay() { @@ -18,13 +28,7 @@ void UMetaCastBaseline::BeginPlay() InitPointCloudReference(); InitInputBindings(); InitSelectionObject(); - - //check if left hand is assigned otherwise assign it to self - if(!LeftHandComponent) - { - UE_LOG(LogTemp, Warning, TEXT("Left Hand not assigned. Please assign in Blueprint => Defaulting to self")); - LeftHandComponent = this; - } + InitLeftHand(); } void UMetaCastBaseline::InitPointCloudReference() diff --git a/Source/MetaCastBachelor/MetaCastBaseline.h b/Source/MetaCastBachelor/MetaCastBaseline.h index 5b3f4bd..c27aa36 100644 --- a/Source/MetaCastBachelor/MetaCastBaseline.h +++ b/Source/MetaCastBachelor/MetaCastBaseline.h @@ -60,6 +60,7 @@ public: // Sets default values for this component's properties UMetaCastBaseline(); + void InitLeftHand(); void InitInputBindings(); virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance); virtual void HandleMetaErasePressed(const FInputActionInstance& Instance); diff --git a/Source/MetaCastBachelor/PointCloud.cpp b/Source/MetaCastBachelor/PointCloud.cpp index a5f6813..284d3f9 100644 --- a/Source/MetaCastBachelor/PointCloud.cpp +++ b/Source/MetaCastBachelor/PointCloud.cpp @@ -91,7 +91,7 @@ void APointCloud::SetupDensityFieldFromPointCloud() const { UE_LOG(LogTemp, Log, TEXT("Initializing DensityField!")); - const FIntVector AxisNumbers(100, 100, 100); + const FIntVector AxisNumbers(200, 200, 200); MyDensityField->InitializeDensityField(this, MinBounds, MaxBounds, AxisNumbers); } -- GitLab