From 6d3574d6d3a692402632ee91e3841bc7cc021a92 Mon Sep 17 00:00:00 2001 From: Christian Heinemann Date: Sun, 29 Dec 2024 10:40:01 +0100 Subject: [PATCH] energy cost for muscle cells --- source/EngineGpuKernels/AttackerProcessor.cuh | 43 +++++-------------- .../CellConnectionProcessor.cuh | 2 +- source/EngineGpuKernels/CellProcessor.cuh | 2 +- source/EngineGpuKernels/MuscleProcessor.cuh | 12 ++++++ .../EngineGpuKernels/RadiationProcessor.cuh | 27 +++++++++++- .../EngineInterface/SimulationParameters.cpp | 3 ++ source/EngineInterface/SimulationParameters.h | 1 + .../Gui/SimulationParametersBaseWidgets.cpp | 12 ++++++ .../AuxiliaryDataParserService.cpp | 6 +++ 9 files changed, 72 insertions(+), 36 deletions(-) diff --git a/source/EngineGpuKernels/AttackerProcessor.cuh b/source/EngineGpuKernels/AttackerProcessor.cuh index df5f7f2fe..dd05f3ea3 100644 --- a/source/EngineGpuKernels/AttackerProcessor.cuh +++ b/source/EngineGpuKernels/AttackerProcessor.cuh @@ -19,7 +19,6 @@ public: private: __inline__ __device__ static void processCell(SimulationData& data, SimulationStatistics& statistics, Cell* cell); - __inline__ __device__ static void radiate(SimulationData& data, Cell* cell); __inline__ __device__ static void distributeEnergy(SimulationData& data, Cell* cell, float energyDelta); __inline__ __device__ static float calcOpenAngle(Cell* cell, float2 direction); @@ -191,9 +190,18 @@ __device__ __inline__ void AttackerProcessor::processCell(SimulationData& data, } } - radiate(data, cell); + // radiation + auto cellFunctionWeaponEnergyCost = SpotCalculator::calcParameter( + &SimulationParametersZoneValues::cellFunctionAttackerEnergyCost, + &SimulationParametersZoneActivatedValues::cellFunctionAttackerEnergyCost, + data, + cell->pos, + cell->color); + if (cellFunctionWeaponEnergyCost > 0) { + RadiationProcessor::radiate(data, cell, cellFunctionWeaponEnergyCost); + } - //output + // output signal.channels[0] = energyDelta / 10; if (energyDelta > NEAR_ZERO) { @@ -206,35 +214,6 @@ __device__ __inline__ void AttackerProcessor::processCell(SimulationData& data, CellFunctionProcessor::setSignal(cell, signal); } -__device__ __inline__ void AttackerProcessor::radiate(SimulationData& data, Cell* cell) -{ - auto cellFunctionWeaponEnergyCost = SpotCalculator::calcParameter( - &SimulationParametersZoneValues::cellFunctionAttackerEnergyCost, - &SimulationParametersZoneActivatedValues::cellFunctionAttackerEnergyCost, - data, - cell->pos, - cell->color); - if (cellFunctionWeaponEnergyCost > 0) { - auto const cellEnergy = atomicAdd(&cell->energy, 0); - - auto const radiationEnergy = min(cellEnergy, cellFunctionWeaponEnergyCost); - auto origEnergy = atomicAdd(&cell->energy, -radiationEnergy); - if (origEnergy < 1.0f) { - atomicAdd(&cell->energy, radiationEnergy); //revert - return; - } - - float2 particleVel = (cell->vel * cudaSimulationParameters.radiationVelocityMultiplier) - + float2{ - (data.numberGen1.random() - 0.5f) * cudaSimulationParameters.radiationVelocityPerturbation, - (data.numberGen1.random() - 0.5f) * cudaSimulationParameters.radiationVelocityPerturbation}; - float2 particlePos = cell->pos + Math::normalized(particleVel) * 1.5f - particleVel; - data.cellMap.correctPosition(particlePos); - - RadiationProcessor::radiate(data, particlePos, particleVel, cell->color, radiationEnergy); - } -} - __device__ __inline__ void AttackerProcessor::distributeEnergy(SimulationData& data, Cell* cell, float energyDelta) { auto const& energyDistribution = cudaSimulationParameters.cellFunctionAttackerEnergyDistributionValue[cell->color]; diff --git a/source/EngineGpuKernels/CellConnectionProcessor.cuh b/source/EngineGpuKernels/CellConnectionProcessor.cuh index cccc090c3..75a65c15d 100644 --- a/source/EngineGpuKernels/CellConnectionProcessor.cuh +++ b/source/EngineGpuKernels/CellConnectionProcessor.cuh @@ -153,7 +153,7 @@ __inline__ __device__ void CellConnectionProcessor::processDeleteCellOperations( Cell* empty = nullptr; auto origCell = alienAtomicExch(&data.objects.cellPointers.at(cellIndex), empty); if (origCell) { - RadiationProcessor::radiate(data, origCell->pos, origCell->vel, origCell->color, origCell->energy); + RadiationProcessor::createEnergyParticle(data, origCell->pos, origCell->vel, origCell->color, origCell->energy); for (int i = 0; i < origCell->numConnections; ++i) { StructuralOperation operation; diff --git a/source/EngineGpuKernels/CellProcessor.cuh b/source/EngineGpuKernels/CellProcessor.cuh index 78de4d116..add85a0b8 100644 --- a/source/EngineGpuKernels/CellProcessor.cuh +++ b/source/EngineGpuKernels/CellProcessor.cuh @@ -764,7 +764,7 @@ __inline__ __device__ void CellProcessor::radiation(SimulationData& data) if (energyLoss > cellEnergy - 1) { energyLoss = cellEnergy - 1; } - RadiationProcessor::radiate(data, particlePos, particleVel, cell->color, energyLoss); + RadiationProcessor::createEnergyParticle(data, particlePos, particleVel, cell->color, energyLoss); cell->energy -= energyLoss; } } diff --git a/source/EngineGpuKernels/MuscleProcessor.cuh b/source/EngineGpuKernels/MuscleProcessor.cuh index df1076bc7..1e09d2a73 100644 --- a/source/EngineGpuKernels/MuscleProcessor.cuh +++ b/source/EngineGpuKernels/MuscleProcessor.cuh @@ -22,6 +22,7 @@ private: __inline__ __device__ static int getConnectionIndex(Cell* cell, Cell* otherCell); __inline__ __device__ static bool hasTriangularConnection(Cell* cell, Cell* otherCell); __inline__ __device__ static float getTruncatedUnitValue(Signal const& signal, int channel = 0); + __inline__ __device__ static void radiate(SimulationData& data, Cell* cell); }; /************************************************************************/ @@ -120,6 +121,7 @@ __device__ __inline__ void MuscleProcessor::movement(SimulationData& data, Simul cell->cellFunctionData.muscle.lastMovementY = direction.y; cell->releaseLock(); statistics.incNumMuscleActivities(cell->color); + radiate(data, cell); } __device__ __inline__ void MuscleProcessor::contractionExpansion(SimulationData& data, SimulationStatistics& statistics, Cell* cell, Signal const& signal) @@ -155,6 +157,7 @@ __device__ __inline__ void MuscleProcessor::contractionExpansion(SimulationData& } cell->releaseLock(); statistics.incNumMuscleActivities(cell->color); + radiate(data, cell); } __inline__ __device__ void MuscleProcessor::bending(SimulationData& data, SimulationStatistics& statistics, Cell* cell, Signal const& signal) @@ -217,6 +220,7 @@ __inline__ __device__ void MuscleProcessor::bending(SimulationData& data, Simula } cell->releaseLock(); statistics.incNumMuscleActivities(cell->color); + radiate(data, cell); } __inline__ __device__ int MuscleProcessor::getConnectionIndex(Cell* cell, Cell* otherCell) @@ -250,3 +254,11 @@ __inline__ __device__ float MuscleProcessor::getTruncatedUnitValue(Signal const& { return max(-0.3f, min(0.3f, signal.channels[channel])) / 0.3f; } + +__inline__ __device__ void MuscleProcessor::radiate(SimulationData& data, Cell* cell) +{ + auto cellFunctionMuscleEnergyCost = cudaSimulationParameters.cellFunctionMuscleEnergyCost[cell->color]; + if (cellFunctionMuscleEnergyCost > 0) { + RadiationProcessor::radiate(data, cell, cellFunctionMuscleEnergyCost); + } +} diff --git a/source/EngineGpuKernels/RadiationProcessor.cuh b/source/EngineGpuKernels/RadiationProcessor.cuh index e231020a4..d793042f8 100644 --- a/source/EngineGpuKernels/RadiationProcessor.cuh +++ b/source/EngineGpuKernels/RadiationProcessor.cuh @@ -18,7 +18,9 @@ public: __inline__ __device__ static void collision(SimulationData& data); __inline__ __device__ static void splitting(SimulationData& data); __inline__ __device__ static void transformation(SimulationData& data); - __inline__ __device__ static void radiate(SimulationData& data, float2 pos, float2 vel, int color, float energy); //return needed energy + + __inline__ __device__ static void radiate(SimulationData& data, Cell* cell, float energy); + __inline__ __device__ static void createEnergyParticle(SimulationData& data, float2 pos, float2 vel, int color, float energy); private: static auto constexpr MaxFusionEnergy = 5.0f; @@ -222,7 +224,28 @@ __inline__ __device__ void RadiationProcessor::transformation(SimulationData& da } } -__inline__ __device__ void RadiationProcessor::radiate(SimulationData& data, float2 pos, float2 vel, int color, float energy) +__inline__ __device__ void RadiationProcessor::radiate(SimulationData& data, Cell* cell, float energy) +{ + auto const cellEnergy = atomicAdd(&cell->energy, 0); + + auto const radiationEnergy = min(cellEnergy, energy); + auto origEnergy = atomicAdd(&cell->energy, -radiationEnergy); + if (origEnergy < 1.0f) { + atomicAdd(&cell->energy, radiationEnergy); //revert + return; + } + + float2 particleVel = (cell->vel * cudaSimulationParameters.radiationVelocityMultiplier) + + float2{ + (data.numberGen1.random() - 0.5f) * cudaSimulationParameters.radiationVelocityPerturbation, + (data.numberGen1.random() - 0.5f) * cudaSimulationParameters.radiationVelocityPerturbation}; + float2 particlePos = cell->pos + Math::normalized(particleVel) * 1.5f - particleVel; + data.cellMap.correctPosition(particlePos); + + RadiationProcessor::createEnergyParticle(data, particlePos, particleVel, cell->color, radiationEnergy); +} + +__inline__ __device__ void RadiationProcessor::createEnergyParticle(SimulationData& data, float2 pos, float2 vel, int color, float energy) { auto numActiveSources = data.preprocessedSimulationData.activeRadiationSources.getNumActiveSources(); if (numActiveSources > 0) { diff --git a/source/EngineInterface/SimulationParameters.cpp b/source/EngineInterface/SimulationParameters.cpp index 7e57c5384..47c8a95b4 100644 --- a/source/EngineInterface/SimulationParameters.cpp +++ b/source/EngineInterface/SimulationParameters.cpp @@ -149,6 +149,9 @@ bool SimulationParameters::operator==(SimulationParameters const& other) const if (genomeComplexityDepthLevel[i] != other.genomeComplexityDepthLevel[i]) { return false; } + if (cellFunctionMuscleEnergyCost[i] != other.cellFunctionMuscleEnergyCost[i]) { + return false; + } } for (int i = 0; i < MAX_COLORS; ++i) { for (int j = 0; j < MAX_COLORS; ++j) { diff --git a/source/EngineInterface/SimulationParameters.h b/source/EngineInterface/SimulationParameters.h index 09db57da5..ab93f8fcf 100644 --- a/source/EngineInterface/SimulationParameters.h +++ b/source/EngineInterface/SimulationParameters.h @@ -187,6 +187,7 @@ struct SimulationParameters ColorVector cellFunctionMuscleBendingAcceleration = {0.15f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f, 0.15f}; float cellFunctionMuscleBendingAccelerationThreshold = 0.1f; bool cellFunctionMuscleMovementTowardTargetedObject = true; + ColorVector cellFunctionMuscleEnergyCost = {0, 0, 0, 0, 0, 0, 0}; ColorVector cellFunctionSensorRange = {255.0f, 255.0f, 255.0f, 255.0f, 255.0f, 255.0f, 255.0f}; float cellFunctionSensorSignalThreshold = 0.1f; diff --git a/source/Gui/SimulationParametersBaseWidgets.cpp b/source/Gui/SimulationParametersBaseWidgets.cpp index d90ca4748..d62a13ae5 100644 --- a/source/Gui/SimulationParametersBaseWidgets.cpp +++ b/source/Gui/SimulationParametersBaseWidgets.cpp @@ -880,6 +880,18 @@ void _SimulationParametersBaseWidgets::process() .tooltip("If activated, a muscle cell in movement mode will only move if the triggering signal originates from a sensor cell that has " "targeted an object. The specified angle in the input is interpreted relative to the target."), parameters.cellFunctionMuscleMovementTowardTargetedObject); + AlienImGui::SliderFloat( + AlienImGui::SliderFloatParameters() + .name("Energy cost") + .textWidth(RightColumnWidth) + .colorDependence(true) + .min(0) + .max(1.0f) + .format("%.5f") + .logarithmic(true) + .defaultValue(origParameters.cellFunctionMuscleEnergyCost) + .tooltip("Amount of energy lost by a muscle action of a cell in form of emitted energy particles."), + parameters.cellFunctionMuscleEnergyCost); AlienImGui::SliderFloat( AlienImGui::SliderFloatParameters() .name("Movement acceleration") diff --git a/source/PersisterInterface/AuxiliaryDataParserService.cpp b/source/PersisterInterface/AuxiliaryDataParserService.cpp index e0ea07b29..354d0be32 100644 --- a/source/PersisterInterface/AuxiliaryDataParserService.cpp +++ b/source/PersisterInterface/AuxiliaryDataParserService.cpp @@ -633,6 +633,12 @@ namespace defaultParameters.cellFunctionMuscleMovementTowardTargetedObject, "simulation parameters.cell.function.muscle.movement toward targeted object", parserTask); + ParameterParser::encodeDecode( + tree, + parameters.cellFunctionMuscleEnergyCost, + defaultParameters.cellFunctionMuscleEnergyCost, + "simulation parameters.cell.function.muscle.energy cost", + parserTask); ParameterParser::encodeDecode( tree,