17#ifndef TOYMAKERENGINE_PHYSICSSYSTEM_H
18#define TOYMAKERENGINE_PHYSICSSYSTEM_H
20#include <unordered_set>
22#include <nlohmann/json.hpp>
48 class PhysicsSystem:
public System<PhysicsSystem, std::tuple<PhysicsState, ObjectBounds>, std::tuple<>>,
public SignalTracker {
95 explicit PhysicsSystem(std::weak_ptr<ECSWorld> world):
114 assert(newSubsteps > 0 &&
"Substeps must be 1 or greater");
132 template<
typename TConstraint,
141 const typename TConstraint::Config& config,
142 const std::vector<std::pair<EntityID, typename TConstraint::Parameter>>& parameters,
152 template<
typename TConstra
int>
160 template<
typename TConstra
int>
257 void integrateForces(
float substepSeconds, std::unordered_map<EntityID, PhysicsStateFull>& previousState, std::unordered_map<EntityID, PhysicsStateFull>& currentState);
263 void deriveVelocities(
float substepSeconds,
const std::unordered_map<EntityID, PhysicsStateFull>& previousState, std::unordered_map<EntityID, PhysicsStateFull>& currentState);
269 void applyPositionCollisionConstraints(std::map<CollisionPair, ConstraintContactManifold>& potentialCollisions,
float substepSeconds, std::unordered_map<EntityID, PhysicsStateFull>& currentState);
275 void applyVelocityCollisionConstraints(std::map<CollisionPair, ConstraintContactManifold>& constraints,
float substepSeconds, std::unordered_map<EntityID, PhysicsStateFull>& currentState);
281 void applyPositionConstraints(std::map<CollisionPair, ConstraintContactManifold>& constraints,
float substepSeconds, std::unordered_map<EntityID, PhysicsStateFull>& currentState);
287 void applyVelocityConstraints(std::map<CollisionPair, ConstraintContactManifold>& constraints,
float substepSeconds, std::unordered_map<EntityID, PhysicsStateFull>& currentState);
297 std::map<CollisionPair, ConstraintContactManifold>& potentialCollisions,
298 std::queue<CollisionReport>& queuedReports,
299 std::unordered_map<EntityID, PhysicsStateFull>& previousStates,
300 std::unordered_map<EntityID, PhysicsStateFull>& currentStates,
334 std::queue<CollisionReport>& reports,
335 std::unordered_map<
EntityID, std::pair<SignalCollided, SignalSeparated>> signallers
383 std::vector<std::pair<std::unique_ptr<BaseConstraint>, std::vector<EntityID>>>
mConstraints {};
462 template<
typename TConstraint,
471 const typename TConstraint::Config& config,
472 const std::vector<std::pair<EntityID, typename TConstraint::Parameter>>& participants,
483 std::unordered_set<EntityID> registeredEntities {};
484 std::vector<EntityID> entities {};
485 std::vector<typename TConstraint::Parameter> constraintData {};
486 for(
const std::pair<EntityID, typename TConstraint::Parameter>& participant: participants) {
487 const bool alreadyRegistered {
488 registeredEntities.find(participant.first) != registeredEntities.end()
490 assert(!alreadyRegistered &&
"An entity has appeared twice in the constraint registration list, which is invalid.");
491 constraintData.push_back(participant.second);
492 entities.push_back(participant.first);
493 registeredEntities.insert(participant.first);
499 std::make_unique<TConstraint>(config, constraintData, compliance),
504 std::make_unique<TConstraint>(config, constraintData, compliance),
509 for(
const auto& entity: entities) {
513 return newConstraint;
516 template<
typename TConstra
int>
518 return static_cast<TConstraint
>(*
mConstraints.at(constraint).first);
521 template<
typename TConstra
int>
523 return static_cast<TConstraint
>(*
mConstraints.at(constraint).first);
Names two distinct entities participating in a collision, with their entity IDs sorted in ascending o...
Definition sweep_prune.hpp:29
Subclass implementation for any constraint which takes data of type TParameter.
Definition types.hpp:716
void applyVelocityConstraints(std::map< CollisionPair, ConstraintContactManifold > &constraints, float substepSeconds, std::unordered_map< EntityID, PhysicsStateFull > ¤tState)
Applies all active velocity constraints.
Definition system.cpp:327
std::queue< CollisionReport > mCollisionReports
Storage for collision reports that should be signalled this simulation frame.
Definition system.hpp:421
void onEntityEnabled(EntityID entityID) override
Updates this entity's physics properties.
Definition system.cpp:476
TConstraint & getConstraint(ConstraintID constraint)
Returns a mutable reference to a constraint for viewing and modification.
Definition system.hpp:517
void onEntityUpdated(EntityID entityID, ComponentType updatedComponent) override
Updates this entity's physics properties.
Definition system.cpp:510
uint8_t getSubsteps() const
Gets the number of substeps used in the physics solver's XPBD implementation.
Definition system.hpp:122
void unregisterCollisionSignal(EntityID entity)
Unregisters collision signals for this entity.
Definition system.cpp:602
std::size_t ConstraintID
ID naming a unique constraint registered with the physics system.
Definition system.hpp:56
std::pair< CollisionPair, Collision > SignalCollidedData
Struct containing data about a collision event.
Definition system.hpp:62
static std::string getSystemTypeName()
The system type string for this class.
Definition system.hpp:105
void integrateForces(float substepSeconds, std::unordered_map< EntityID, PhysicsStateFull > &previousState, std::unordered_map< EntityID, PhysicsStateFull > ¤tState)
Derives position and rotation updates for physics objects based on their current state and forces act...
Definition system.cpp:68
void onSeparated(const CollisionPair &pair, std::queue< CollisionReport > &queuedReports)
Removes pair of entities from collision list, appending collision event to queue if required.
Definition system.cpp:662
bool mRequiresInitialization
Whether physics properties for all eligible entities should be recomputed.
Definition system.hpp:450
bool wasColliding(const CollisionPair &pair) const
Whether or not a particular pair of entities have their collision tracked by the physics system.
Definition system.cpp:622
uint8_t mSubsteps
The number of substeps used in the physics system's XPBD implementation.
Definition system.hpp:444
std::unordered_map< EntityID, PhysicsStateFull > mEntityStatePrevious
Storage for local entity states prior to the integration step each substep.
Definition system.hpp:362
void updateProperties(EntityID entityID)
Computes rotational inertia from mass and object bounds.
Definition system.cpp:536
std::shared_ptr< Signal< SignalCollidedData > > SignalCollided
Signal for reporting collision start events.
Definition system.hpp:74
void onSimulationActivated() override
Marks this system as requiring initialization on the nearest update.
Definition system.cpp:18
void setSubsteps(uint8_t newSubsteps)
Sets the number of substeps used for physics integration using XPBD.
Definition system.hpp:113
std::unordered_map< EntityID, std::set< ConstraintID > > mEntityConstraintMap
Associates each entity with its set of constraints, used to determine whether the constraint can be e...
Definition system.hpp:375
std::unordered_set< EntityID > mPotentialColliders
A list of entities that may collide this frame.
Definition system.hpp:415
void applyPositionConstraints(std::map< CollisionPair, ConstraintContactManifold > &constraints, float substepSeconds, std::unordered_map< EntityID, PhysicsStateFull > ¤tState)
Applies all active position constraints.
Definition system.cpp:281
bool mConstraintsInitialized
Whether we have yet to determine which constraints are active and which are not.
Definition system.hpp:456
SweepPrune mBroadPhase
Representation of the structure/technique being used to detect likely collisions.
Definition system.hpp:403
ConstraintID registerConstraint(const typename TConstraint::Config &config, const std::vector< std::pair< EntityID, typename TConstraint::Parameter > > ¶meters, float compliance)
Registers a constraint for the physics system to evaluate every substep.
Definition system.hpp:470
static const std::string SignalSeparatedPrefix
Prefix for the name under which separated Signals are advertised.
Definition system.hpp:93
void collectPotentialCollisions(float substepSeconds, std::queue< CollisionReport > &queuedReports)
Collects potential collisions and builds constraints from them.
Definition system.cpp:142
std::unordered_map< EntityID, ConstraintDampingRigidbody > mEntityDamping
Mapping of entities to their velocity damping constraints.
Definition system.hpp:395
std::unordered_map< EntityID, PhysicsStateFull > mEntityStateCurrent
Storage for current local entity states, eventually pushed to ECS component tables.
Definition system.hpp:368
bool isConstraintActive(ConstraintID constraint) const
Whether or not a particular constraint is active.
Definition system.cpp:522
std::shared_ptr< Signal< SignalSeparatedData > > SignalSeparated
Signal for reporting the separation of two colliding bodies.
Definition system.hpp:80
std::map< CollisionPair, ConstraintContactManifold > mCollisionConstraints
Storage for pairs of entities that are likely to collide (or are colliding) this simulation frame.
Definition system.hpp:433
void updateCollisionEventQueue(std::map< CollisionPair, ConstraintContactManifold > &potentialCollisions, std::queue< CollisionReport > &queuedReports, std::unordered_map< EntityID, PhysicsStateFull > &previousStates, std::unordered_map< EntityID, PhysicsStateFull > ¤tStates, uint8_t nthSubstep)
Tests each pair of potential colliders for intersection, adds collision report to the queue if config...
Definition system.cpp:429
void deriveVelocities(float substepSeconds, const std::unordered_map< EntityID, PhysicsStateFull > &previousState, std::unordered_map< EntityID, PhysicsStateFull > ¤tState)
Derives actual object velocities after integration and constraint solve.
Definition system.cpp:387
void reportCollisions(std::queue< CollisionReport > &reports, std::unordered_map< EntityID, std::pair< SignalCollided, SignalSeparated > > signallers) const
Signals all collisions and separations collected over the course of the simulation step,...
Definition system.cpp:693
void unregisterConstraint(ConstraintID constraint)
Removes a constraint.
Definition system.cpp:514
static const std::string SignalCollidedPrefix
Prefix for the name under which collided Signals are advertised.
Definition system.hpp:87
void refreshActiveConstraints()
Determines which constraints are inactive (by virtue of all of their entities being enabled) and whic...
std::set< EntityID > mEntitiesUninitialized
Holds entities that haven't undergone proper initialization, and therefore aren't eligible for proper...
Definition system.hpp:356
void onEntityDisabled(EntityID entityID) override
Removes entity from to-initialize list.
Definition system.cpp:481
void onCollided(const CollisionPair &pair, const Collision &collision, std::queue< CollisionReport > &queuedReports)
Registers a pair of entities as intersecting, signalling to collision signal observers if required.
Definition system.cpp:636
CollisionPair SignalSeparatedData
Struct containing data about a separation event.
Definition system.hpp:68
void applyVelocityCollisionConstraints(std::map< CollisionPair, ConstraintContactManifold > &constraints, float substepSeconds, std::unordered_map< EntityID, PhysicsStateFull > ¤tState)
Correctly applies collision velocity constraint for each potential collision detected.
Definition system.cpp:370
std::vector< std::pair< std::unique_ptr< BaseConstraint >, std::vector< EntityID > > > mConstraints
A list of all constraints known to the physics system, evaluated every frame.
Definition system.hpp:383
void onSimulationStep(uint32_t timestepMillis) override
Updates physics simulation.
Definition system.cpp:22
std::unordered_map< EntityID, std::pair< SignalCollided, SignalSeparated > > mCollisionSignallers
Entities whose collision events are signalled by this system.
Definition system.hpp:427
void applyPositionCollisionConstraints(std::map< CollisionPair, ConstraintContactManifold > &potentialCollisions, float substepSeconds, std::unordered_map< EntityID, PhysicsStateFull > ¤tState)
Correctly applies collision position constraint for each potential collision detected.
Definition system.cpp:259
void registerCollisionSignal(EntityID entity)
Registers collision signals for this entity.
Definition system.cpp:606
std::unordered_map< EntityID, std::unordered_set< EntityID > > mEntityCollision
All currently intersecting entities.
Definition system.hpp:409
std::unordered_set< ConstraintID > mConstraintsDeleted
IDs of constraints that were deleted and which may be reused to define a new constraint.
Definition system.hpp:389
SignalTracker()
Constructs a new SignalTracker object.
A class designed around finding which pairs of AABBs may be intersecting (so as to limit the number o...
Definition sweep_prune.hpp:85
A system template that disables systems with this form of declaration.
Definition ecs_world.hpp:1085
ToyMaker Engine's implementation of an ECS system.
ECSType ComponentType
An unsigned integer representing the type of a component.
Definition ecs_world.hpp:101
std::uint64_t EntityID
A single unsigned integer used as a name for an entity managed by an ECS system.
Definition ecs_world.hpp:66
Namespace containing all class definitions and functions related to the ToyMaker engine.
Definition application.hpp:26
Classes relating to this engine's implementation of signals. Contains template classes used to define...
Classes and structs representing data related to the engine's spatial query system (the precursor to ...
Data representing everything about a collision.
Definition types.hpp:816
A component defining the true bounds of a spatially queryable object situated somewhere in the world.
Definition types.hpp:845
Component representing the physics state of the body it's attached to at some particular point in tim...
Definition types.hpp:142
Definition system.hpp:183
bool mCollided
Whether this report corresponds to a collided or separated event.
Definition system.hpp:188
Definition system.hpp:172
Acceleration structure for finding pairs of objects whose AABBs are intersecting.
Definition system.hpp:178