Skip to content
Snippets Groups Projects
Commit 067a2e94 authored by Timon Römer's avatar Timon Römer
Browse files

Adds Redo and Erase

parent 47a868cf
No related branches found
No related tags found
No related merge requests found
Showing
with 129 additions and 60 deletions
#include "MagicWand.h" #include "MagicWand.h"
#include "Utilities.h"
#include "FMagicWandSelectionTask.h" #include "FMagicWandSelectionTask.h"
#include "Components/LineBatchComponent.h" #include "Components/LineBatchComponent.h"
#include "Generators/MarchingCubes.h" #include "Generators/MarchingCubes.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "MetaCastBachelor/PointStorage/PointCloud.h"
// INITIALIZATION // INITIALIZATION
...@@ -309,7 +309,7 @@ void UMagicWand::HandleMetaSelectPressed(const FInputActionInstance& Instance) ...@@ -309,7 +309,7 @@ void UMagicWand::HandleMetaSelectPressed(const FInputActionInstance& Instance)
SeedPointIndex = INDEX_NONE; SeedPointIndex = INDEX_NONE;
const FVector SelectionStartPositionWorld = SelectionObject->GetComponentLocation(); const FVector SelectionStartPositionWorld = SelectionObject->GetComponentLocation();
const FVector SelectionStartPositionLocal = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionStartPositionWorld); const FVector SelectionStartPositionLocal = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().InverseTransformPosition(SelectionStartPositionWorld);
FindSeed(SelectionStartPositionLocal); FindSeed(SelectionStartPositionLocal);
if(SeedPointIndex == INDEX_NONE) return; if(SeedPointIndex == INDEX_NONE) return;
...@@ -338,10 +338,12 @@ void UMagicWand::HandleMetaSelectReleased(const FInputActionInstance& Instance) ...@@ -338,10 +338,12 @@ void UMagicWand::HandleMetaSelectReleased(const FInputActionInstance& Instance)
{ {
if(SelectionArray[i].Value.load()) if(SelectionArray[i].Value.load())
{ {
MyPointCloud->SelectionFlags[i] = true; MyPointCloud->SetSelectionFlag(i, true);
} }
} }
MyPointCloud->SaveStateAndUpdate();
//CurrentSelection.Reset(); //CurrentSelection.Reset();
} }
...@@ -355,12 +357,33 @@ void UMagicWand::HandleMetaEraseReleased(const FInputActionInstance& Instance) ...@@ -355,12 +357,33 @@ void UMagicWand::HandleMetaEraseReleased(const FInputActionInstance& Instance)
} }
//AbortMagicWand.Store(true); //AbortMagicWand.Store(true);
CurrentSelection = MakeShared<FSelectionManager>(MyPointCloud->SelectionFlags.Num(), MyDensityField->GetVoxelNumber()); if(EraseSound) UGameplayStatics::PlaySound2D(World, EraseSound);
CurrentSelection = MakeShared<FSelectionManager>(MyPointCloud->GetNumberOfPoints(), MyDensityField->GetVoxelNumber());
for(int i = 0; i < MyPointCloud->GetNumberOfPoints(); i++)
{
MyPointCloud->SetSelectionFlag(i, false);
}
for(int i = 0; i < MyPointCloud->SelectionFlags.Num(); i++) MyPointCloud->SaveStateAndUpdate();
}
void UMagicWand::HandleUndoAction(const FInputActionInstance& Instance)
{ {
MyPointCloud->SelectionFlags[i] = false; Super::HandleUndoAction(Instance);
if(NumberThreads.GetValue() > 0) return;
if(UndoSound) UGameplayStatics::PlaySound2D(World, UndoSound);
MyPointCloud->Undo();
} }
void UMagicWand::HandleRedoAction(const FInputActionInstance& Instance)
{
Super::HandleRedoAction(Instance);
if(NumberThreads.GetValue() > 0) return;
if(RedoSound) UGameplayStatics::PlaySound2D(World, RedoSound);
MyPointCloud->Redo();
} }
// MAGIC WAND SELECTION // MAGIC WAND SELECTION
...@@ -374,12 +397,6 @@ void UMagicWand::InitMagicWandSelection() ...@@ -374,12 +397,6 @@ void UMagicWand::InitMagicWandSelection()
void UMagicWand::PerformMagicWandSelection(const float ProximityThreshold) void UMagicWand::PerformMagicWandSelection(const float ProximityThreshold)
{ {
if (MyPointCloud->SelectionFlags.Num() != MyPointCloud->PositionVectors.Num())
{
UE_LOG(LogTemp, Error, TEXT("PerformMagicWandSelection: Positions and SelectionFlags array sizes do not match."));
return;
}
if (SeedPointIndex == INDEX_NONE) return; if (SeedPointIndex == INDEX_NONE) return;
if(SelectionStartSound) UGameplayStatics::PlaySound2D(World, SelectionStartSound); if(SelectionStartSound) UGameplayStatics::PlaySound2D(World, SelectionStartSound);
...@@ -432,7 +449,7 @@ void UMagicWand::FindSeed(const FVector& InputPosition) ...@@ -432,7 +449,7 @@ void UMagicWand::FindSeed(const FVector& InputPosition)
for(const int32 CurrentIndex : PointIndices) for(const int32 CurrentIndex : PointIndices)
{ {
FVector CurrentPosition = MyPointCloud->PositionVectors[CurrentIndex]; FVector CurrentPosition = MyPointCloud->GetPositionVectors()[CurrentIndex];
const float Distance = FVector::Dist(InputPosition, CurrentPosition); const float Distance = FVector::Dist(InputPosition, CurrentPosition);
if (Distance < MinDistance) if (Distance < MinDistance)
{ {
...@@ -444,7 +461,7 @@ void UMagicWand::FindSeed(const FVector& InputPosition) ...@@ -444,7 +461,7 @@ void UMagicWand::FindSeed(const FVector& InputPosition)
if(SeedPointIndex != INDEX_NONE) if(SeedPointIndex != INDEX_NONE)
{ {
SeedPointPositionLocal = MyPointCloud->PositionVectors[SeedPointIndex]; SeedPointPositionLocal = MyPointCloud->GetPositionVectors()[SeedPointIndex];
} }
} }
...@@ -461,9 +478,9 @@ void UMagicWand::ExpandFromAllPointsInQueue(TQueue<int32>* ProcessQueue, const f ...@@ -461,9 +478,9 @@ void UMagicWand::ExpandFromAllPointsInQueue(TQueue<int32>* ProcessQueue, const f
int32 CurrentQueuePointIndex; int32 CurrentQueuePointIndex;
ProcessQueue->Dequeue(CurrentQueuePointIndex); ProcessQueue->Dequeue(CurrentQueuePointIndex);
if(MyPointCloud && MyPointCloud->PositionVectors.IsValidIndex(CurrentQueuePointIndex)) if(MyPointCloud && MyPointCloud->GetPositionVectors().IsValidIndex(CurrentQueuePointIndex))
{ {
const FVector CurrentQueuePointPosition = MyPointCloud->PositionVectors[CurrentQueuePointIndex]; const FVector CurrentQueuePointPosition = MyPointCloud->GetPositionVectors()[CurrentQueuePointIndex];
ExpandFromPoint(ProcessQueue, ProximityThreshold, ThreadLoad, CurrentQueuePointPosition, &MyVoxelPointLookupTable); ExpandFromPoint(ProcessQueue, ProximityThreshold, ThreadLoad, CurrentQueuePointPosition, &MyVoxelPointLookupTable);
} }
...@@ -477,12 +494,12 @@ void UMagicWand::ExpandFromAllPointsInQueue(TQueue<int32>* ProcessQueue, const f ...@@ -477,12 +494,12 @@ void UMagicWand::ExpandFromAllPointsInQueue(TQueue<int32>* ProcessQueue, const f
void UMagicWand::ExpandFromPoint(TQueue<int32>* ProcessQueue, const float ProximityThreshold, int& ThreadLoad, const FVector& ExpansionPoint, const FVoxelPointLookupTable* MyVoxelPointLookupTable) const void UMagicWand::ExpandFromPoint(TQueue<int32>* ProcessQueue, const float ProximityThreshold, int& ThreadLoad, const FVector& ExpansionPoint, const FVoxelPointLookupTable* MyVoxelPointLookupTable) const
{ {
const FVector Step = MyDensityField->GetStep(); const FVector Step = MyDensityField->GetStep();
const int32 StartX = FMath::Max(0, FMath::FloorToInt((ExpansionPoint.X - ProximityThreshold - MyPointCloud->MinBounds.X) / Step.X)); const int32 StartX = FMath::Max(0, FMath::FloorToInt((ExpansionPoint.X - ProximityThreshold - MyPointCloud->GetMinBounds().X) / Step.X));
const int32 EndX = FMath::Min(MyDensityField->GetXNum() - 1, FMath::FloorToInt((ExpansionPoint.X + ProximityThreshold - MyPointCloud->MinBounds.X) / Step.X)); const int32 EndX = FMath::Min(MyDensityField->GetXNum() - 1, FMath::FloorToInt((ExpansionPoint.X + ProximityThreshold - MyPointCloud->GetMinBounds().X) / Step.X));
const int32 StartY = FMath::Max(0, FMath::FloorToInt((ExpansionPoint.Y - ProximityThreshold - MyPointCloud->MinBounds.Y) / Step.Y)); const int32 StartY = FMath::Max(0, FMath::FloorToInt((ExpansionPoint.Y - ProximityThreshold - MyPointCloud->GetMinBounds().Y) / Step.Y));
const int32 EndY = FMath::Min(MyDensityField->GetYNum() - 1, FMath::FloorToInt((ExpansionPoint.Y + ProximityThreshold - MyPointCloud->MinBounds.Y) / Step.Y)); const int32 EndY = FMath::Min(MyDensityField->GetYNum() - 1, FMath::FloorToInt((ExpansionPoint.Y + ProximityThreshold - MyPointCloud->GetMinBounds().Y) / Step.Y));
const int32 StartZ = FMath::Max(0, FMath::FloorToInt((ExpansionPoint.Z - ProximityThreshold - MyPointCloud->MinBounds.Z) / Step.Z)); const int32 StartZ = FMath::Max(0, FMath::FloorToInt((ExpansionPoint.Z - ProximityThreshold - MyPointCloud->GetMinBounds().Z) / Step.Z));
const int32 EndZ = FMath::Min(MyDensityField->GetZNum() - 1, FMath::FloorToInt((ExpansionPoint.Z + ProximityThreshold - MyPointCloud->MinBounds.Z) / Step.Z)); const int32 EndZ = FMath::Min(MyDensityField->GetZNum() - 1, FMath::FloorToInt((ExpansionPoint.Z + ProximityThreshold - MyPointCloud->GetMinBounds().Z) / Step.Z));
const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold; const float SquaredProximityThreshold = ProximityThreshold * ProximityThreshold;
...@@ -511,7 +528,7 @@ void UMagicWand::ExpandFromPoint(TQueue<int32>* ProcessQueue, const float Proxim ...@@ -511,7 +528,7 @@ void UMagicWand::ExpandFromPoint(TQueue<int32>* ProcessQueue, const float Proxim
continue; continue;
} }
FVector CurrentComparisonPosition = MyPointCloud->PositionVectors[CurrentPointComparisonIndex]; FVector CurrentComparisonPosition = MyPointCloud->GetPositionVectors()[CurrentPointComparisonIndex];
const double SquaredDistance = FVector::DistSquared(ExpansionPoint, CurrentComparisonPosition); const double SquaredDistance = FVector::DistSquared(ExpansionPoint, CurrentComparisonPosition);
if (SquaredDistance <= SquaredProximityThreshold) if (SquaredDistance <= SquaredProximityThreshold)
...@@ -551,9 +568,9 @@ void UMagicWand::FinishSelectionThread(const float ProximityThreshold) ...@@ -551,9 +568,9 @@ void UMagicWand::FinishSelectionThread(const float ProximityThreshold)
for (int32 i = 0; i < PointIndices.Num(); i++) for (int32 i = 0; i < PointIndices.Num(); i++)
{ {
const int Index = PointIndices[i]; const int Index = PointIndices[i];
if(MyPointCloud->PositionVectors.IsValidIndex(Index)) if(MyPointCloud->GetPositionVectors().IsValidIndex(Index))
{ {
FVector Point = MyPointCloud->PositionVectors[Index]; FVector Point = MyPointCloud->GetPositionVectors()[Index];
int32 VoxelFromIndex = MyDensityField->WorldPositionToIndex(Point); int32 VoxelFromIndex = MyDensityField->WorldPositionToIndex(Point);
Voxels.Add(VoxelFromIndex); Voxels.Add(VoxelFromIndex);
} }
...@@ -616,7 +633,7 @@ TSharedPtr<FSelectionManager> UMagicWand::GetSelectionCacheResultCopy(const floa ...@@ -616,7 +633,7 @@ TSharedPtr<FSelectionManager> UMagicWand::GetSelectionCacheResultCopy(const floa
} }
// If no valid selection manager is found, create a new one and add it to the map // If no valid selection manager is found, create a new one and add it to the map
TSharedPtr<FSelectionManager> NewManager = MakeShared<FSelectionManager>(MyPointCloud->SelectionFlags.Num(), MyDensityField->GetVoxelNumber()); TSharedPtr<FSelectionManager> NewManager = MakeShared<FSelectionManager>(MyPointCloud->GetNumberOfPoints(), MyDensityField->GetVoxelNumber());
SelectionCache.Add(ProximityThreshold, NewManager); SelectionCache.Add(ProximityThreshold, NewManager);
SortedProximityRanges.Add(ProximityThreshold); SortedProximityRanges.Add(ProximityThreshold);
SortedProximityRanges.Sort(); SortedProximityRanges.Sort();
...@@ -643,14 +660,14 @@ void UMagicWand::SelectParticles(const FVector& InputPosition) ...@@ -643,14 +660,14 @@ void UMagicWand::SelectParticles(const FVector& InputPosition)
if(!IsMagicWandInitialized) return; if(!IsMagicWandInitialized) return;
const FVector CurrentSelectionPositionWorld = SelectionObject->GetComponentLocation(); const FVector CurrentSelectionPositionWorld = SelectionObject->GetComponentLocation();
const FVector CurrentSelectionPositionLocal = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(CurrentSelectionPositionWorld); const FVector CurrentSelectionPositionLocal = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().InverseTransformPosition(CurrentSelectionPositionWorld);
const float ProximityThreshold = FMath::Clamp(FVector::Dist(SeedPointPositionLocal, CurrentSelectionPositionLocal) / ThresholdDistanceScaling, MinThreshold, MaxThreshold); const float ProximityThreshold = FMath::Clamp(FVector::Dist(SeedPointPositionLocal, CurrentSelectionPositionLocal) / ThresholdDistanceScaling, MinThreshold, MaxThreshold);
const FVector SelectionDirectionLocal = CurrentSelectionPositionLocal - SeedPointPositionLocal; const FVector SelectionDirectionLocal = CurrentSelectionPositionLocal - SeedPointPositionLocal;
const FVector ProximityEndPointLocal = SeedPointPositionLocal + (SelectionDirectionLocal.GetSafeNormal() * ProximityThreshold); const FVector ProximityEndPointLocal = SeedPointPositionLocal + (SelectionDirectionLocal.GetSafeNormal() * ProximityThreshold);
const FVector SelectionStartPositionWorld = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(SeedPointPositionLocal); const FVector SelectionStartPositionWorld = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().TransformPosition(SeedPointPositionLocal);
const FVector ProximityEndPointWorld = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(ProximityEndPointLocal); const FVector ProximityEndPointWorld = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().TransformPosition(ProximityEndPointLocal);
GenerateCylinderBetweenPoints(SelectionStartPositionWorld, ProximityEndPointWorld, 0.05, 8, FColor::Red, 1); GenerateCylinderBetweenPoints(SelectionStartPositionWorld, ProximityEndPointWorld, 0.05, 8, FColor::Red, 1);
GenerateCylinderBetweenPoints((CurrentSelectionPositionWorld - ProximityEndPointWorld).GetSafeNormal() * 0.05 + ProximityEndPointWorld, CurrentSelectionPositionWorld, 0.05, 8, FColor::Green, 0); GenerateCylinderBetweenPoints((CurrentSelectionPositionWorld - ProximityEndPointWorld).GetSafeNormal() * 0.05 + ProximityEndPointWorld, CurrentSelectionPositionWorld, 0.05, 8, FColor::Green, 0);
......
...@@ -80,6 +80,15 @@ class UMagicWand : public UMetaCastBaseline ...@@ -80,6 +80,15 @@ class UMagicWand : public UMetaCastBaseline
UPROPERTY(EditAnywhere) UPROPERTY(EditAnywhere)
USoundWave* SelectionStartSound; USoundWave* SelectionStartSound;
UPROPERTY(EditAnywhere)
USoundWave* UndoSound;
UPROPERTY(EditAnywhere)
USoundWave* RedoSound;
UPROPERTY(EditAnywhere)
USoundWave* EraseSound;
public: public:
int32 SeedPointIndex; int32 SeedPointIndex;
...@@ -95,6 +104,8 @@ public: ...@@ -95,6 +104,8 @@ public:
virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override; virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override;
virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override; virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override;
virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance) override; virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance) override;
virtual void HandleUndoAction(const FInputActionInstance& Instance) override;
virtual void HandleRedoAction(const FInputActionInstance& Instance) override;
virtual void EraseParticles(const FVector& InputPosition) override; virtual void EraseParticles(const FVector& InputPosition) override;
// VISUALIZATION // VISUALIZATION
......
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
#include "EnhancedInputComponent.h" #include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h" #include "EnhancedInputSubsystems.h"
UMetaCastBaseline::UMetaCastBaseline() : UMetaCastBaseline::UMetaCastBaseline() : SelectionObject(nullptr), EnhancedInputComponent(nullptr), MetaSelectAction(nullptr), MetaEraseAction(nullptr), UndoAction(nullptr), RedoAction(nullptr), InputMappingContext(nullptr), LeftHandComponent(nullptr), MyPointCloud(nullptr)
SelectionObject(nullptr), EnhancedInputComponent(nullptr), MetaSelectAction(nullptr), MetaEraseAction(nullptr),
InputMappingContext(nullptr), LeftHandComponent(nullptr), MyPointCloud(nullptr)
{ {
PrimaryComponentTick.bCanEverTick = true; PrimaryComponentTick.bCanEverTick = true;
} }
...@@ -78,6 +76,16 @@ void UMetaCastBaseline::InitInputBindings() ...@@ -78,6 +76,16 @@ void UMetaCastBaseline::InitInputBindings()
UE_LOG(LogTemp, Error, TEXT("MetaEraseAction is not set. Please assign it in the editor.")); UE_LOG(LogTemp, Error, TEXT("MetaEraseAction is not set. Please assign it in the editor."));
} }
if (!UndoAction)
{
UE_LOG(LogTemp, Error, TEXT("UndoAction is not set. Please assign it in the editor."));
}
if (!RedoAction)
{
UE_LOG(LogTemp, Error, TEXT("RedoAction is not set. Please assign it in the editor."));
}
const APlayerController* PlayerController = GetWorld()->GetFirstPlayerController(); const APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
if(!PlayerController) if(!PlayerController)
...@@ -103,10 +111,13 @@ void UMetaCastBaseline::InitInputBindings() ...@@ -103,10 +111,13 @@ void UMetaCastBaseline::InitInputBindings()
EnhancedInputComponent->BindAction(MetaSelectAction, ETriggerEvent::Started, this, &UMetaCastBaseline::HandleMetaSelectPressed); EnhancedInputComponent->BindAction(MetaSelectAction, ETriggerEvent::Started, this, &UMetaCastBaseline::HandleMetaSelectPressed);
EnhancedInputComponent->BindAction(MetaSelectAction, ETriggerEvent::Completed, this, &UMetaCastBaseline::HandleMetaSelectReleased); EnhancedInputComponent->BindAction(MetaSelectAction, ETriggerEvent::Completed, this, &UMetaCastBaseline::HandleMetaSelectReleased);
EnhancedInputComponent->BindAction(MetaSelectAction, ETriggerEvent::Canceled, this, &UMetaCastBaseline::HandleMetaSelectReleased);
EnhancedInputComponent->BindAction(MetaEraseAction, ETriggerEvent::Started, this, &UMetaCastBaseline::HandleMetaErasePressed); EnhancedInputComponent->BindAction(MetaEraseAction, ETriggerEvent::Started, this, &UMetaCastBaseline::HandleMetaErasePressed);
EnhancedInputComponent->BindAction(MetaEraseAction, ETriggerEvent::Completed, this, &UMetaCastBaseline::HandleMetaEraseReleased); EnhancedInputComponent->BindAction(MetaEraseAction, ETriggerEvent::Completed, this, &UMetaCastBaseline::HandleMetaEraseReleased);
EnhancedInputComponent->BindAction(UndoAction, ETriggerEvent::Completed, this, &UMetaCastBaseline::HandleUndoAction);
EnhancedInputComponent->BindAction(RedoAction, ETriggerEvent::Completed, this, &UMetaCastBaseline::HandleRedoAction);
} }
} }
...@@ -130,6 +141,14 @@ void UMetaCastBaseline::HandleMetaEraseReleased(const FInputActionInstance& Inst ...@@ -130,6 +141,14 @@ void UMetaCastBaseline::HandleMetaEraseReleased(const FInputActionInstance& Inst
this->Erase = Instance.GetValue().Get<bool>(); this->Erase = Instance.GetValue().Get<bool>();
} }
void UMetaCastBaseline::HandleUndoAction(const FInputActionInstance& Instance)
{
}
void UMetaCastBaseline::HandleRedoAction(const FInputActionInstance& Instance)
{
}
void UMetaCastBaseline::AttachToHand(const float DeltaTime) const void UMetaCastBaseline::AttachToHand(const float DeltaTime) const
{ {
if (MyPointCloud && LeftHandComponent) if (MyPointCloud && LeftHandComponent)
...@@ -170,40 +189,34 @@ void UMetaCastBaseline::TickComponent(const float DeltaTime, const ELevelTick Ti ...@@ -170,40 +189,34 @@ void UMetaCastBaseline::TickComponent(const float DeltaTime, const ELevelTick Ti
void UMetaCastBaseline::SelectParticles(const FVector& InputPosition) void UMetaCastBaseline::SelectParticles(const FVector& InputPosition)
{ {
if (MyPointCloud->SelectionFlags.Num() != MyPointCloud->PositionVectors.Num()) for (int32 i = 0; i < MyPointCloud->GetNumberOfPoints(); i++)
{
UE_LOG(LogTemp, Warning, TEXT("SelectParticles: Positions and SelectionFlags array sizes do not match."));
return;
}
for (int32 i = 0; i < MyPointCloud->PositionVectors.Num(); i++)
{ {
FVector CurrentPoint = MyPointCloud->PositionVectors[i]; FVector CurrentPoint = MyPointCloud->GetPositionVectors()[i];
CurrentPoint = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(CurrentPoint); CurrentPoint = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().TransformPosition(CurrentPoint);
if ((InputPosition - CurrentPoint).Size() < SelectionRadius / 2 && !MyPointCloud->SelectionFlags[i]) if ((InputPosition - CurrentPoint).Size() < SelectionRadius / 2 && !MyPointCloud->GetSelectionFlag(i))
{ {
MyPointCloud->SelectionFlags[i] = true; // Set the flag to true as it's now selected MyPointCloud->SetSelectionFlag(i, true); // Set the flag to true as it's now selected
} }
} }
} }
void UMetaCastBaseline::EraseParticles(const FVector& InputPosition) void UMetaCastBaseline::EraseParticles(const FVector& InputPosition)
{ {
if (MyPointCloud->SelectionFlags.Num() != MyPointCloud->PositionVectors.Num()) if (MyPointCloud->GetNumberOfPoints() != MyPointCloud->GetPositionVectors().Num())
{ {
UE_LOG(LogTemp, Warning, TEXT("Erase: Positions and SelectionFlags array sizes do not match.")); UE_LOG(LogTemp, Warning, TEXT("Erase: Positions and SelectionFlags array sizes do not match."));
return; return;
} }
for (int32 i = 0; i < MyPointCloud->PositionVectors.Num(); i++) for (int32 i = 0; i < MyPointCloud->GetPositionVectors().Num(); i++)
{ {
FVector CurrentPoint = MyPointCloud->PositionVectors[i]; FVector CurrentPoint = MyPointCloud->GetPositionVectors()[i];
CurrentPoint = MyPointCloud->PointCloudVisualizer->GetComponentTransform().TransformPosition(CurrentPoint); CurrentPoint = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().TransformPosition(CurrentPoint);
if ((InputPosition - CurrentPoint).Size() < SelectionRadius / 2 && !MyPointCloud->SelectionFlags[i]) if ((InputPosition - CurrentPoint).Size() < SelectionRadius / 2 && !MyPointCloud->GetSelectionFlag(i))
{ {
MyPointCloud->SelectionFlags[i] = false; // Set the flag to false as it's now erased MyPointCloud->SetSelectionFlag(i, false); // Set the flag to false as it's now erased
} }
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "InputAction.h" #include "InputAction.h"
#include "Components/SceneComponent.h" #include "Components/SceneComponent.h"
#include "PointCloud.h" #include "MetaCastBachelor/PointStorage/PointCloud.h"
#include "MetaCastBaseline.generated.h" #include "MetaCastBaseline.generated.h"
...@@ -30,6 +30,12 @@ public: ...@@ -30,6 +30,12 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* MetaEraseAction; UInputAction* MetaEraseAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* UndoAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* RedoAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputMappingContext* InputMappingContext; UInputMappingContext* InputMappingContext;
...@@ -62,10 +68,16 @@ public: ...@@ -62,10 +68,16 @@ public:
UMetaCastBaseline(); UMetaCastBaseline();
void InitLeftHand(); void InitLeftHand();
void InitInputBindings(); void InitInputBindings();
virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance); virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance);
virtual void HandleMetaErasePressed(const FInputActionInstance& Instance); virtual void HandleMetaErasePressed(const FInputActionInstance& Instance);
virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance); virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance);
virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance); virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance);
virtual void HandleUndoAction(const FInputActionInstance& Instance);
virtual void HandleRedoAction(const FInputActionInstance& Instance);
void AttachToHand(float DeltaTime) const; void AttachToHand(float DeltaTime) const;
void InitPointCloudReference(); void InitPointCloudReference();
void InitSelectionObject(); void InitSelectionObject();
......
...@@ -14,6 +14,7 @@ UMetaCastInteractable::UMetaCastInteractable() ...@@ -14,6 +14,7 @@ UMetaCastInteractable::UMetaCastInteractable()
} }
// Called when the game starts // Called when the game starts
void UMetaCastInteractable::BeginPlay() void UMetaCastInteractable::BeginPlay()
{ {
......
#include "MetaPoint.h" #include "MetaPoint.h"
#include "Utilities.h"
#include "Generators/MarchingCubes.h" #include "Generators/MarchingCubes.h"
#include "MetaCastBachelor/General/Utilities.h"
#include "MetaCastBachelor/PointStorage/PointCloud.h"
UMetaPoint::UMetaPoint() : LocalMaximumIndex(0), MyDensityField(nullptr), MetaPointThreshold(0), World(nullptr) UMetaPoint::UMetaPoint() : LocalMaximumIndex(0), MyDensityField(nullptr), MetaPointThreshold(0), World(nullptr)
{ {
...@@ -21,7 +22,7 @@ void UMetaPoint::BeginPlay() ...@@ -21,7 +22,7 @@ void UMetaPoint::BeginPlay()
UE_LOG(LogTemp, Warning, TEXT("Invalid world provided.")); UE_LOG(LogTemp, Warning, TEXT("Invalid world provided."));
} }
ProceduralMesh->AttachToComponent(MyPointCloud->PointCloudVisualizer, FAttachmentTransformRules::SnapToTargetIncludingScale); ProceduralMesh->AttachToComponent(MyPointCloud->GetRootComponent(), FAttachmentTransformRules::SnapToTargetIncludingScale);
ProceduralMesh->SetMaterial(0, SelectionVolumeMat); ProceduralMesh->SetMaterial(0, SelectionVolumeMat);
ProceduralMesh->SetMaterial(1, SelectionVolumeMat); ProceduralMesh->SetMaterial(1, SelectionVolumeMat);
ProceduralMesh->SetMaterial(2, SelectionVolumeMat); ProceduralMesh->SetMaterial(2, SelectionVolumeMat);
...@@ -55,10 +56,9 @@ void UMetaPoint::HandleMetaSelectReleased(const FInputActionInstance& Instance) ...@@ -55,10 +56,9 @@ void UMetaPoint::HandleMetaSelectReleased(const FInputActionInstance& Instance)
ProceduralMesh->ClearAllMeshSections(); ProceduralMesh->ClearAllMeshSections();
ProceduralMesh->SetVisibility(false); ProceduralMesh->SetVisibility(false);
AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]() AsyncTask(ENamedThreads::Type::AnyBackgroundHiPriTask, [this]()
{ {
MyPointCloud->ColorPointsInVoxels(FloodedIndices); MyPointCloud->SelectAllPointsInVoxels(FloodedIndices);
}); });
} }
...@@ -74,10 +74,23 @@ void UMetaPoint::HandleMetaEraseReleased(const FInputActionInstance& Instance) ...@@ -74,10 +74,23 @@ void UMetaPoint::HandleMetaEraseReleased(const FInputActionInstance& Instance)
Super::HandleMetaEraseReleased(Instance); Super::HandleMetaEraseReleased(Instance);
//deselect all particles //deselect all particles
for (int32 i = 0; i < MyPointCloud->SelectionFlags.Num(); ++i) for (int32 i = 0; i < MyPointCloud->GetNumberOfPoints(); ++i)
{ {
MyPointCloud->SelectionFlags[i] = false; MyPointCloud->SetSelectionFlag(i, false);
}
MyPointCloud->SaveStateAndUpdate();
} }
void UMetaPoint::HandleUndoAction(const FInputActionInstance& Instance)
{
Super::HandleUndoAction(Instance);
MyPointCloud->Undo();
}
void UMetaPoint::HandleRedoAction(const FInputActionInstance& Instance)
{
Super::HandleRedoAction(Instance);
MyPointCloud->Redo();
} }
void UMetaPoint::InitMetaPointSelection() void UMetaPoint::InitMetaPointSelection()
...@@ -86,7 +99,7 @@ void UMetaPoint::InitMetaPointSelection() ...@@ -86,7 +99,7 @@ void UMetaPoint::InitMetaPointSelection()
MyDensityField = MyPointCloud->MyDensityField; MyDensityField = MyPointCloud->MyDensityField;
// Convert the world position of the selection object to the local position relative to the point cloud // Convert the world position of the selection object to the local position relative to the point cloud
const FVector SelectionLocalPosition = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition); const FVector SelectionLocalPosition = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition);
// Perform gradient ascent to find the local maximum starting from the converted local position // Perform gradient ascent to find the local maximum starting from the converted local position
LocalMaximum = FUtilities::FollowGradientToMaximum(MyDensityField, SelectionLocalPosition); LocalMaximum = FUtilities::FollowGradientToMaximum(MyDensityField, SelectionLocalPosition);
...@@ -137,7 +150,7 @@ void UMetaPoint::SelectParticles(const FVector& InputPosition) ...@@ -137,7 +150,7 @@ void UMetaPoint::SelectParticles(const FVector& InputPosition)
LastHandInput = SelectionWorldPosition; LastHandInput = SelectionWorldPosition;
// Convert the world position of the selection object to the local position relative to the point cloud // Convert the world position of the selection object to the local position relative to the point cloud
const FVector SelectionLocalPosition = MyPointCloud->PointCloudVisualizer->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition); const FVector SelectionLocalPosition = MyPointCloud->GetPointCloudVisualizer()->GetComponentTransform().InverseTransformPosition(SelectionWorldPosition);
// Perform gradient ascent to find the local maximum starting from the converted local position // Perform gradient ascent to find the local maximum starting from the converted local position
LocalMaximum = FUtilities::FollowGradientToMaximum(MyDensityField, SelectionLocalPosition); LocalMaximum = FUtilities::FollowGradientToMaximum(MyDensityField, SelectionLocalPosition);
......
...@@ -59,6 +59,8 @@ public: ...@@ -59,6 +59,8 @@ public:
virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override; virtual void HandleMetaSelectReleased(const FInputActionInstance& Instance) override;
virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override; virtual void HandleMetaSelectPressed(const FInputActionInstance& Instance) override;
virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance) override; virtual void HandleMetaEraseReleased(const FInputActionInstance& Instance) override;
virtual void HandleUndoAction(const FInputActionInstance& Instance) override;
virtual void HandleRedoAction(const FInputActionInstance& Instance) override;
void InitMetaPointSelection(); void InitMetaPointSelection();
void GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const; void GenerateVoxelMeshWithCubes(const TArray<int32> Voxels) const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment