diff --git a/source/EngineGpuKernels/EditKernels.cu b/source/EngineGpuKernels/EditKernels.cu index 9b9ffcd1a..544abc55b 100644 --- a/source/EngineGpuKernels/EditKernels.cu +++ b/source/EngineGpuKernels/EditKernels.cu @@ -239,17 +239,20 @@ __global__ void cudaUpdateAngleAndAngularVelForSelection(ShallowUpdateSelectionD } } -__global__ void cudaCalcAccumulatedCenterAndVel(SimulationData data, float2* center, float2* velocity, int* numEntities, bool includeClusters) +__global__ void cudaCalcAccumulatedCenterAndVel(SimulationData data, int refCellIndex, float2* center, float2* velocity, int* numEntities, bool includeClusters) { { + float2 refPos = refCellIndex != -1 ? data.objects.cellPointers.at(refCellIndex)->pos : float2{0, 0}; + auto const partition = calcAllThreadsPartition(data.objects.cellPointers.getNumEntries()); for (int index = partition.startIndex; index <= partition.endIndex; ++index) { auto const& cell = data.objects.cellPointers.at(index); if (isSelected(cell, includeClusters)) { if (center) { - atomicAdd(¢er->x, cell->pos.x); - atomicAdd(¢er->y, cell->pos.y); + auto pos = cell->pos + data.cellMap.getCorrectionIncrement(refPos, cell->pos); + atomicAdd(¢er->x, pos.x); + atomicAdd(¢er->y, pos.y); } if (velocity) { atomicAdd(&velocity->x, cell->vel.x); @@ -574,8 +577,22 @@ __global__ void cudaResetSelectionResult(SelectionResult result) result.reset(); } -__global__ void cudaGetSelectionShallowData(SimulationData data, float2 refPos, SelectionResult result) +__global__ void cudaCalcCellWithMinimalPosY(SimulationData data, unsigned long long int* minCellPosYAndIndex) +{ + auto const cellBlock = calcAllThreadsPartition(data.objects.cellPointers.getNumEntries()); + + for (int index = cellBlock.startIndex; index <= cellBlock.endIndex; ++index) { + auto const& cell = data.objects.cellPointers.at(index); + if (0 != cell->selected) { + atomicMin(minCellPosYAndIndex, (static_cast(abs(cell->pos.y)) << 32) | static_cast(index)); + } + } +} + +__global__ void cudaGetSelectionShallowData(SimulationData data, int refCellIndex, SelectionResult result) { + float2 refPos = refCellIndex != 0xffffffff ? data.objects.cellPointers.at(refCellIndex)->pos : float2{0, 0}; + auto const cellBlock = calcAllThreadsPartition(data.objects.cellPointers.getNumEntries()); for (int index = cellBlock.startIndex; index <= cellBlock.endIndex; ++index) { diff --git a/source/EngineGpuKernels/EditKernels.cuh b/source/EngineGpuKernels/EditKernels.cuh index 5f304e7fa..0fd9a5f9a 100644 --- a/source/EngineGpuKernels/EditKernels.cuh +++ b/source/EngineGpuKernels/EditKernels.cuh @@ -29,7 +29,7 @@ __global__ void cudaScheduleConnectSelection(SimulationData data, bool considerW __global__ void cudaPrepareMapForReconnection(SimulationData data); __global__ void cudaUpdateMapForReconnection(SimulationData data); __global__ void cudaUpdateAngleAndAngularVelForSelection(ShallowUpdateSelectionData updateData, SimulationData data, float2 center); -__global__ void cudaCalcAccumulatedCenterAndVel(SimulationData data, float2* center, float2* velocity, int* numEntities, bool includeClusters); +__global__ void cudaCalcAccumulatedCenterAndVel(SimulationData data, int refCellIndex, float2* center, float2* velocity, int* numEntities, bool includeClusters); __global__ void cudaIncrementPosAndVelForSelection(ShallowUpdateSelectionData updateData, SimulationData data); __global__ void cudaSetVelocityForSelection(SimulationData data, float2 velocity, bool includeClusters); __global__ void cudaMakeSticky(SimulationData data, bool includeClusters); @@ -47,7 +47,8 @@ __global__ void cudaSwapSelection(float2 pos, float radius, SimulationData data) __global__ void cudaRolloutSelectionStep(SimulationData data, int* result); __global__ void cudaApplyForce(SimulationData data, ApplyForceData applyData); __global__ void cudaResetSelectionResult(SelectionResult result); -__global__ void cudaGetSelectionShallowData(SimulationData data, float2 refPos, SelectionResult result); +__global__ void cudaCalcCellWithMinimalPosY(SimulationData data, unsigned long long int* minCellPosYAndIndex); +__global__ void cudaGetSelectionShallowData(SimulationData data, int refCellIndex, SelectionResult result); __global__ void cudaFinalizeSelectionResult(SelectionResult result, BaseMap map); __global__ void cudaSetDetached(SimulationData data, bool value); __global__ void cudaApplyCataclysm(SimulationData data); diff --git a/source/EngineGpuKernels/EditKernelsLauncher.cu b/source/EngineGpuKernels/EditKernelsLauncher.cu index cc7ff31ba..08b3a29b4 100644 --- a/source/EngineGpuKernels/EditKernelsLauncher.cu +++ b/source/EngineGpuKernels/EditKernelsLauncher.cu @@ -13,6 +13,7 @@ _EditKernelsLauncher::_EditKernelsLauncher() CudaMemoryManager::getInstance().acquireMemory(1, _cudaCenter); CudaMemoryManager::getInstance().acquireMemory(1, _cudaVelocity); CudaMemoryManager::getInstance().acquireMemory(1, _cudaNumEntities); + CudaMemoryManager::getInstance().acquireMemory(1, _cudaMinCellPosYAndIndex); _garbageCollector = std::make_shared<_GarbageCollectorKernelsLauncher>(); } @@ -25,6 +26,7 @@ _EditKernelsLauncher::~_EditKernelsLauncher() CudaMemoryManager::getInstance().freeMemory(_cudaCenter); CudaMemoryManager::getInstance().freeMemory(_cudaVelocity); CudaMemoryManager::getInstance().freeMemory(_cudaNumEntities); + CudaMemoryManager::getInstance().freeMemory(_cudaMinCellPosYAndIndex); } void _EditKernelsLauncher::removeSelection(GpuSettings const& gpuSettings, SimulationData const& data) @@ -64,14 +66,14 @@ void _EditKernelsLauncher::updateSelection(GpuSettings const& gpuSettings, Simul rolloutSelection(gpuSettings, data); } -void _EditKernelsLauncher::getSelectionShallowData( - GpuSettings const& gpuSettings, - SimulationData const& data, - float2 const& refPos, - SelectionResult const& selectionResult) +void _EditKernelsLauncher::getSelectionShallowData(GpuSettings const& gpuSettings, SimulationData const& data, SelectionResult const& selectionResult) { KERNEL_CALL_1_1(cudaResetSelectionResult, selectionResult); - KERNEL_CALL(cudaGetSelectionShallowData, data, refPos, selectionResult); + setValueToDevice(_cudaMinCellPosYAndIndex, 0xffffffffffffffff); + KERNEL_CALL(cudaCalcCellWithMinimalPosY, data, _cudaMinCellPosYAndIndex); + cudaDeviceSynchronize(); + auto refCellIndex = static_cast(copyToHost(_cudaMinCellPosYAndIndex) & 0xffffffff); + KERNEL_CALL(cudaGetSelectionShallowData, data, refCellIndex, selectionResult); KERNEL_CALL_1_1(cudaFinalizeSelectionResult, selectionResult, data.cellMap); } @@ -103,7 +105,13 @@ void _EditKernelsLauncher::shallowUpdateSelectedObjects( if (updateData.angleDelta != 0 || updateData.angularVelDelta != 0) { setValueToDevice(_cudaCenter, float2{0, 0}); setValueToDevice(_cudaNumEntities, 0); - KERNEL_CALL(cudaCalcAccumulatedCenterAndVel, data, _cudaCenter, nullptr, _cudaNumEntities, updateData.considerClusters); + + setValueToDevice(_cudaMinCellPosYAndIndex, 0xffffffff00000000); + KERNEL_CALL(cudaCalcCellWithMinimalPosY, data, _cudaMinCellPosYAndIndex); + cudaDeviceSynchronize(); + auto refCellIndex = static_cast(copyToHost(_cudaMinCellPosYAndIndex) & 0xffffffff); + + KERNEL_CALL(cudaCalcAccumulatedCenterAndVel, data, refCellIndex, _cudaCenter, nullptr, _cudaNumEntities, updateData.considerClusters); cudaDeviceSynchronize(); auto numEntities = copyToHost(_cudaNumEntities); @@ -158,7 +166,7 @@ void _EditKernelsLauncher::uniformVelocities(GpuSettings const& gpuSettings, Sim { setValueToDevice(_cudaVelocity, float2{0, 0}); setValueToDevice(_cudaNumEntities, 0); - KERNEL_CALL(cudaCalcAccumulatedCenterAndVel, data, nullptr, _cudaVelocity, _cudaNumEntities, includeClusters); + KERNEL_CALL(cudaCalcAccumulatedCenterAndVel, data, -1, nullptr, _cudaVelocity, _cudaNumEntities, includeClusters); cudaDeviceSynchronize(); auto numEntities = copyToHost(_cudaNumEntities); diff --git a/source/EngineGpuKernels/EditKernelsLauncher.cuh b/source/EngineGpuKernels/EditKernelsLauncher.cuh index 004d76afd..bd807f8fc 100644 --- a/source/EngineGpuKernels/EditKernelsLauncher.cuh +++ b/source/EngineGpuKernels/EditKernelsLauncher.cuh @@ -18,7 +18,7 @@ public: void setSelection(GpuSettings const& gpuSettings, SimulationData const& data, AreaSelectionData const& setData); void updateSelection(GpuSettings const& gpuSettings, SimulationData const& data); - void getSelectionShallowData(GpuSettings const& gpuSettings, SimulationData const& data, float2 const& refPos, SelectionResult const& selectionResult); + void getSelectionShallowData(GpuSettings const& gpuSettings, SimulationData const& data, SelectionResult const& selectionResult); void shallowUpdateSelectedObjects( GpuSettings const& gpuSettings, SimulationData const& data, @@ -51,4 +51,5 @@ private: float2* _cudaCenter; float2* _cudaVelocity; int* _cudaNumEntities; + unsigned long long int* _cudaMinCellPosYAndIndex; }; diff --git a/source/EngineGpuKernels/SimulationCudaFacade.cu b/source/EngineGpuKernels/SimulationCudaFacade.cu index bf2d49014..fa0220fe4 100644 --- a/source/EngineGpuKernels/SimulationCudaFacade.cu +++ b/source/EngineGpuKernels/SimulationCudaFacade.cu @@ -335,9 +335,9 @@ void _SimulationCudaFacade::setSelection(AreaSelectionData const& selectionData) _editKernels->setSelection(_settings.gpuSettings, getSimulationDataIntern(), selectionData); } - SelectionShallowData _SimulationCudaFacade::getSelectionShallowData(float2 const& refPos) + SelectionShallowData _SimulationCudaFacade::getSelectionShallowData() { - _editKernels->getSelectionShallowData(_settings.gpuSettings, getSimulationDataIntern(), refPos, * _cudaSelectionResult); + _editKernels->getSelectionShallowData(_settings.gpuSettings, getSimulationDataIntern(), *_cudaSelectionResult); syncAndCheck(); return _cudaSelectionResult->getSelectionShallowData(); } diff --git a/source/EngineGpuKernels/SimulationCudaFacade.cuh b/source/EngineGpuKernels/SimulationCudaFacade.cuh index 9812801b0..d2a39c005 100644 --- a/source/EngineGpuKernels/SimulationCudaFacade.cuh +++ b/source/EngineGpuKernels/SimulationCudaFacade.cuh @@ -60,7 +60,7 @@ public: void switchSelection(PointSelectionData const& switchData); void swapSelection(PointSelectionData const& selectionData); void setSelection(AreaSelectionData const& selectionData); - SelectionShallowData getSelectionShallowData(float2 const& refPos); + SelectionShallowData getSelectionShallowData(); void shallowUpdateSelectedObjects(ShallowUpdateSelectionData const& shallowUpdateData); void removeSelection(); void updateSelection(); diff --git a/source/EngineImpl/EngineWorker.cpp b/source/EngineImpl/EngineWorker.cpp index 170cc8ea7..74c8415b8 100644 --- a/source/EngineImpl/EngineWorker.cpp +++ b/source/EngineImpl/EngineWorker.cpp @@ -399,10 +399,10 @@ void EngineWorker::swapSelection(RealVector2D const& pos, float radius) _simulationCudaFacade->swapSelection(PointSelectionData{{pos.x, pos.y}, radius}); } -SelectionShallowData EngineWorker::getSelectionShallowData(RealVector2D const& refPos) +SelectionShallowData EngineWorker::getSelectionShallowData() { EngineWorkerGuard access(this); - return _simulationCudaFacade->getSelectionShallowData({refPos.x, refPos.y}); + return _simulationCudaFacade->getSelectionShallowData(); } void EngineWorker::setSelection(RealVector2D const& startPos, RealVector2D const& endPos) diff --git a/source/EngineImpl/EngineWorker.h b/source/EngineImpl/EngineWorker.h index 14d8773d0..8ee296302 100644 --- a/source/EngineImpl/EngineWorker.h +++ b/source/EngineImpl/EngineWorker.h @@ -95,7 +95,7 @@ class EngineWorker void switchSelection(RealVector2D const& pos, float radius); void swapSelection(RealVector2D const& pos, float radius); - SelectionShallowData getSelectionShallowData(RealVector2D const& refPos); + SelectionShallowData getSelectionShallowData(); void setSelection(RealVector2D const& startPos, RealVector2D const& endPos); void removeSelection(); void updateSelection(); diff --git a/source/EngineImpl/SimulationFacadeImpl.cpp b/source/EngineImpl/SimulationFacadeImpl.cpp index 9ff619ded..8b6133506 100644 --- a/source/EngineImpl/SimulationFacadeImpl.cpp +++ b/source/EngineImpl/SimulationFacadeImpl.cpp @@ -302,9 +302,9 @@ void _SimulationFacadeImpl::swapSelection(RealVector2D const& pos, float radius) _worker.swapSelection(pos, radius); } -SelectionShallowData _SimulationFacadeImpl::getSelectionShallowData(RealVector2D const& refPos) +SelectionShallowData _SimulationFacadeImpl::getSelectionShallowData() { - return _worker.getSelectionShallowData(refPos); + return _worker.getSelectionShallowData(); } void _SimulationFacadeImpl::shallowUpdateSelectedObjects(ShallowUpdateSelectionData const& updateData) diff --git a/source/EngineImpl/SimulationFacadeImpl.h b/source/EngineImpl/SimulationFacadeImpl.h index 12176f2e0..fd490a7e9 100644 --- a/source/EngineImpl/SimulationFacadeImpl.h +++ b/source/EngineImpl/SimulationFacadeImpl.h @@ -94,7 +94,7 @@ class _SimulationFacadeImpl : public _SimulationFacade void switchSelection(RealVector2D const& pos, float radius) override; void swapSelection(RealVector2D const& pos, float radius) override; - SelectionShallowData getSelectionShallowData(RealVector2D const& refPos = RealVector2D()) override; + SelectionShallowData getSelectionShallowData() override; void shallowUpdateSelectedObjects(ShallowUpdateSelectionData const& updateData) override; void setSelection(RealVector2D const& startPos, RealVector2D const& endPos) override; void removeSelection() override; diff --git a/source/EngineInterface/SimulationFacade.h b/source/EngineInterface/SimulationFacade.h index 963bce394..40b4496ea 100644 --- a/source/EngineInterface/SimulationFacade.h +++ b/source/EngineInterface/SimulationFacade.h @@ -84,7 +84,7 @@ class _SimulationFacade virtual void switchSelection(RealVector2D const& pos, float radius) = 0; virtual void swapSelection(RealVector2D const& pos, float radius) = 0; - virtual SelectionShallowData getSelectionShallowData(RealVector2D const& refPos = RealVector2D()) = 0; + virtual SelectionShallowData getSelectionShallowData() = 0; virtual void shallowUpdateSelectedObjects(ShallowUpdateSelectionData const& updateData) = 0; virtual void setSelection(RealVector2D const& startPos, RealVector2D const& endPos) = 0; virtual void removeSelection() = 0; diff --git a/source/Gui/EditorController.cpp b/source/Gui/EditorController.cpp index c180fb5d6..0525992ec 100644 --- a/source/Gui/EditorController.cpp +++ b/source/Gui/EditorController.cpp @@ -264,7 +264,7 @@ void EditorController::onMoveSelectedObjects( void EditorController::onFixateSelectedObjects(RealVector2D const& viewPos, RealVector2D const& prevWorldPos, RealVector2D const& selectionPositionOnClick) { - auto shallowData = _simulationFacade->getSelectionShallowData(selectionPositionOnClick); + auto shallowData = _simulationFacade->getSelectionShallowData(); auto selectionPosition = RealVector2D{shallowData.centerPosX, shallowData.centerPosY}; auto selectionDelta = selectionPosition - selectionPositionOnClick; diff --git a/source/Gui/OverlayController.cpp b/source/Gui/OverlayController.cpp index 817ac32a4..a56b92c4c 100644 --- a/source/Gui/OverlayController.cpp +++ b/source/Gui/OverlayController.cpp @@ -96,7 +96,7 @@ void OverlayController::processProgressAnimation() ImColor::HSV(0.66f, 1.0f, 0.1f, 1.0f), ImColor::HSV(0.66f, 1.0f, 0.1f, 0.0f), ImColor::HSV(0.66f, 1.0f, 0.1f, 0.0f)); - auto N = 6 + toInt(powf(sinf(duration / 500.0f - Const::Pi / 4) + 1, 3.0f) * 5); + auto N = 8 + toInt(powf(sinf(duration / 500.0f - Const::Pi / 4) + 1, 3.0f) * 5); for (int i = 0; i < N; ++i) { auto amplitude1 = sinf(toFloat(i) * 10.0f / toFloat(N) - duration / 700.0f * (1.0f + 0.3f * sinf(duration / 1000))); auto amplitude2 = sinf(toFloat(i) * 14.0f / toFloat(N) - duration / 100.0f * (1.0f + 0.3f * cosf(duration / 1000))); diff --git a/source/Gui/SimulationInteractionController.cpp b/source/Gui/SimulationInteractionController.cpp index 447706419..3c4035589 100644 --- a/source/Gui/SimulationInteractionController.cpp +++ b/source/Gui/SimulationInteractionController.cpp @@ -175,7 +175,7 @@ void SimulationInteractionController::leftMouseButtonPressed(IntVector2D const& _simulationFacade->setDetached(true); } - auto shallowData = _simulationFacade->getSelectionShallowData(*_worldPosOnClick); + auto shallowData = _simulationFacade->getSelectionShallowData(); _selectionPositionOnClick = {shallowData.centerPosX, shallowData.centerPosY}; } else { CreatorWindow::get().onDrawing();