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);
 }