diff --git a/Content/MagicWandMap.umap b/Content/MagicWandMap.umap index bd7492ae734fcd1e7e27825d4ae8845abe574fec..5abed2d8bc29ddf32c4cf888d4f03b16036d6e0a 100644 Binary files a/Content/MagicWandMap.umap and b/Content/MagicWandMap.umap differ diff --git a/Source/MetaCastBachelor/MagicWand.cpp b/Source/MetaCastBachelor/MagicWand.cpp index 4b2f64b31da4379dd4a162aac5eccaa57b57b51b..cda7616003f4c7a6dd4ba2e7be5c4a8acf406c6b 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 e84de2e169ddbefc7983caa6f739693055a0104a..0037e3b9903341dbef0a4d4090f9e6e4d506cf2d 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 0000000000000000000000000000000000000000..01628e5618aa8dd41ea6b25b09ad18b7f65ea297 --- /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 f6bd224b4e055da59cc4b63d22e578552b94d58a..6485e9d66fbf1f9b00c58da7bd3fe0e17de9a230 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 5b3f4bdf9d096135fcc9aff2442d0d223649a0de..c27aa364137be80b37f1063eb7fa8f7ee0b560cd 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 a5f6813ffe3a9127732fc9946fb34915cc576035..284d3f91dd1b6f2206b155e7080b892c08ebea34 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); }