93 friend class ::SpaceTest;
104 explicit Space(
const Configuration::SimulationConfig& config);
171 [[nodiscard]] std::tuple<Vector3dVec, QuaterniondVec>
180 [[nodiscard]] std::tuple<Vector3dVec, QuaterniondVec, Vector3dVec,
183 void printProfilingReport()
const;
190 [[nodiscard]]
double getG()
const {
return G_; }
359 [[nodiscard]] std::tuple<Vector3d, double, double>
378 const Vector3d& impulseN);
432 void colorGraph(
const std::vector<std::vector<std::size_t>>& graph);
469 const Vector3d& direction_vec);
624 std::vector<std::vector<std::pair<std::size_t, std::size_t>>>
SoA container for simulation bodies and proxies for AoS-like access.
Structure-of-Arrays (SoA) container for all bodies in the simulation.
std::size_t size() const
Get number of bodies in the simulation.
A proxy object that provides an AoS-like interface to a body stored in the Bodies SoA container.
A const proxy object that provides a read-only AoS-like interface to a body stored in the Bodies SoA ...
Class describing a space in which move several bodies.
Vector3d applyFrictionImpulse(const CollisionContext &ctx, double jn, const Vector3d &impulseN)
Calculates the tangential (frictional) impulse for a collision.
double G_
Universal gravitational constant (in m³ / kg /s²).
double profCollisionResponse_
Time spent in collision response.
~Space()
Destructor to clean up OpenMP locks.
double previous_dt_
Previous time step (in s).
double getTimeStep() const
Get the current time step.
double coeffStaticFriction_
Coefficient of static friction.
void initializeBodies(std::size_t n, double dens, unsigned int seed)
Initialises the bodies in the simulation with random properties.
void applyGravity()
Calculates and applies gravitational forces to all bodies.
std::tuple< Vector3dVec, QuaterniondVec, Vector3dVec, Vector3dVec > getDataForDisplay() const
Retrieves all data required for display for all bodies.
double getPositionalCorrectionFactor() const
Get the positional correction factor.
std::vector< omp_lock_t > graphLocks_
OpenMP locks for thread-safe collision graph updates.
double getCoeffFriction() const
Get the coefficient of kinetic friction.
BodyProxy body(std::size_t i)
Get a proxy to the i-th body.
void resolveInterpenetration(const CollisionContext &ctx)
Resolves interpenetration by moving bodies apart along the collision normal.
void setCoeffRestitution(double e)
Set the coefficient of restitution.
double getCoeffStaticFriction() const
Get the coefficient of static friction.
void setLinearDamping(double damping)
Set the linear damping factor.
double getLinearDamping() const
Get the linear damping factor.
double getEffectiveMass(const CollisionContext &ctx, const Vector3d &direction_vec)
Calculates the effective mass of two colliding bodies in a given direction.
void logSystemEnergy(std::size_t iteration)
Logs system energy and checks for instability if diagnostics are enabled.
void resolveCollisions()
Resolves all detected collisions using graph colouring.
void setPositionalCorrectionFactor(double factor)
Set the positional correction factor.
void setTimeStep(double dt)
Set the current time step.
void colorGraph(const std::vector< std::vector< std::size_t > > &graph)
A greedy graph colouring algorithm to assign a colour (integer) to each body such that no two adjacen...
void computeDynamics(std::size_t iteration)
Computes one full step of the simulation.
double lastTotalEnergy_
The total energy from the previous logged step.
double linearDamping_
Damping factor for linear velocity.
double getPreviousTimeStep() const
Get the time step used in the last completed simulation frame.
double getG() const
Get the universal gravitational constant.
bool isDiagnosticsEnabled() const
Check if diagnostics are enabled.
std::vector< std::vector< std::size_t > > collisionGraph_
Adjacency list for the collision graph.
double profCollisionGraph_
Time spent in collision graph building.
void setG(double g)
Set the universal gravitational constant.
std::size_t logFreq_
Frequency of energy log output (every N iterations).
std::size_t n() const
Number of bodies getter.
void setCoeffStaticFriction(double mu_s)
Set the coefficient of static friction.
Space()
Default constructor.
Bodies bodies_
SoA container for all bodies in the simulation.
double profIntegration_
Time spent in integration steps.
bool diagnosticsEnabled_
Flag indicating if diagnostic output is enabled.
void setCoeffFriction(double mu)
Set the coefficient of kinetic friction.
double positionalCorrectionFactor_
The percentage of overlap to correct in each frame.
Bodies & getBodiesForTest()
Provides direct access to the Bodies container for testing.
void setEpsilon(double eps)
Set the numerical precision threshold.
ConstBodyProxy body(std::size_t i) const
Get a const proxy to the i-th body.
std::optional< CollisionContext > createCollisionContext(BodyProxy &b1, BodyProxy &b2)
Factory method to create a CollisionContext if two bodies are colliding.
double cached_max_radius_
Cached maximum radius for collision detection optimization. This is recalculated only when bodies are...
double angularDamping_
Damping factor for angular velocity.
double dt_
Time step (in s).
double profForceCalculation_
Time spent in force calculation.
void applyDamping()
Applies linear and angular damping to all bodies.
void updateAdaptiveTimeStep()
Determines the optimal time step for the next frame based on current velocities and accelerations.
void setAngularDamping(double damping)
Set the angular damping factor.
double coeffRestitution_
Coefficient of restitution for collisions.
std::unique_ptr< KDTree > kdTree_
k-d tree for broad-phase collision detection.
std::tuple< Vector3d, double, double > applyRestitutionImpulse(CollisionContext &ctx)
Calculates and applies the normal impulse (restitution) for a collision.
std::vector< std::vector< std::pair< std::size_t, std::size_t > > > thread_local_collision_pairs_
Thread-local storage for collision pairs found during broad-phase. This reduces lock contention on th...
double getCoeffRestitution() const
Get the coefficient of restitution.
void setDiagnosticsEnabled(bool enabled)
Enable or disable diagnostics.
double coeffFriction_
Coefficient of kinetic (sliding) friction.
double epsilon_
Numerical precision threshold.
std::vector< int > colors_
Stores the colour of each body for parallel collision processing.
double getEpsilon() const
Get the numerical precision threshold.
void buildCollisionGraph()
Builds the collision graph using broad-phase and narrow-phase detection.
std::tuple< Vector3dVec, QuaterniondVec > getAllBodyTransforms() const
Retrieves the current positions and orientations of all bodies.
double getAngularDamping() const
Get the angular damping factor.
void handleCollision(BodyProxy &b1, BodyProxy &b2)
Handles collision detection and response between two bodies.
std::tuple< double, double, double > calculateSystemEnergy() const
Calculates the kinetic and potential energy of the system.
constexpr double EPSILON
Default computing precision value.
constexpr double G
Default universal gravitational constant (in m³⋅kg⁻¹⋅s⁻²).
A k-d tree wrapper for broad-phase collision detection using nanoflann.
A data container to hold all relevant information for a single collision event.
Vector3d vRel_
The relative velocity between the two bodies at the contact point.
BodyProxy & b1
A proxy to the first body in the collision.
BodyProxy & b2
A proxy to the second body in the collision.
Vector3d r1Vec_
The vector from the centre of body 1 to the contact point.
Vector3d r2Vec_
The vector from the centre of body 2 to the contact point.
Vector3d nVec_
The normalised vector pointing from body 1 to body 2.
double overlap_
The penetration depth of the two bodies.