17#ifndef TOYMAKERENGINE_PHYSICSTYPES_H
18#define TOYMAKERENGINE_PHYSICSTYPES_H
25#include <nlohmann/json.hpp>
49 const glm::vec3& correctionPoint,
50 const glm::vec3& correctionGradient
69 const glm::vec3& correctionRotational
91 const glm::vec3& impulsePositional,
92 const glm::vec3& impulsePoint
105 const glm::vec3& impulseRotational
117 const glm::vec3& impulsePositional,
118 const glm::vec3& impulsePoint
129 const glm::vec3& impulseRotational
143 using Traits = uint8_t;
353 return std::numeric_limits<float>::max();
364 if(mass == std::numeric_limits<float>::max()) {
390 &&
"Rotational inertia must be valid positive number for each axis"
393 rotationalInertia.x == std::numeric_limits<float>::max()? 0.f: 1.f / rotationalInertia.x,
394 rotationalInertia.y == std::numeric_limits<float>::max()? 0.f: 1.f / rotationalInertia.y,
395 rotationalInertia.z == std::numeric_limits<float>::max()? 0.f: 1.f / rotationalInertia.z,
406 &&
"Restitution coefficient must be non negative and cannot exceed 1"
425 assert(
false &&
"Unrecognized physics type specified");
441 assert(
false &&
"Unrecognized physics type specified");
491 template<u
int8_t LagrangeCount>
494 template <
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
527 using ParticipantID = std::size_t;
529 using ParticipantTable = std::unordered_map<
532 std::reference_wrapper<ObjectBounds>,
533 std::reference_wrapper<PhysicsState>
551 const ParticipantTable& states,
563 const ParticipantTable& states,
584 template <
typename TConstraint,
592 void setParameter(ParticipantID participant,
const typename TConstraint::Parameter& parameter);
598 template <
typename TConstraint,
606 typename TConstraint::Parameter
getParameter(ParticipantID participant)
const;
612 template <
typename TConstraint,
621 void setConfig(
const typename TConstraint::Config& config);
627 template <
typename TConstraint,
635 typename TConstraint::Config
getConfig()
const;
645 template<u
int8_t LagrangeCount>
653 template<uint8_t... ints>
715 template <
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
724 std::unordered_map<BaseConstraint::ParticipantID, TParameter>
mParameters {};
733 using Config = TConfig;
734 using Parameter = TParameter;
735 static const uint8_t NLagrange = LagrangeCount;
742 const TConfig& config,
743 const std::vector<TParameter>& constraintParameters,
763 void setParameter(BaseConstraint::ParticipantID participant,
const TParameter& parameter);
769 inline TParameter
getParameter(BaseConstraint::ParticipantID participant)
const {
783 const std::unordered_map<BaseConstraint::ParticipantID, TParameter>&
getParameters()
const;
884 const ParticipantTable& states,
893 const ParticipantTable& states,
927 const ParticipantTable& states,
936 const ParticipantTable& states,
1000 const ParticipantTable& states,
1001 float substepSeconds
1058 && (!isRotation || (
1084 inline bool isSensible(
bool isRotation=
false)
const {
1126 inline void from_json(
1127 const nlohmann::json& json,
1134 if(json.at(
"mass").is_string() && json.at(
"mass") ==
"infinity") {
1135 mass = std::numeric_limits<float>::max();
1137 mass = json.at(
"mass");
1140 physics.setMass(mass);
1141 physics.setMode(json.at(
"mode"));
1143 if(json.find(
"collision_response") != json.end()) {
1146 physics.setCollisionResponse(response);
1150 if(json.find(
"velocity") != json.end()) {
1151 physics.mVelocity = glm::vec3 {
1152 json.at(
"velocity")[0],
1153 json.at(
"velocity")[1],
1154 json.at(
"velocity")[2],
1156 assert(
isNumber(physics.mVelocity) &&
isFinite(physics.mVelocity) &&
"Velocity must be sensible");
1158 if(json.find(
"velocity_bleed") != json.end()) {
1159 physics.mVelocityBleed = json.at(
"velocity_bleed");
1162 && physics.mVelocityBleed >= 0.f
1163 && physics.mVelocityBleed <= 1.f
1164 &&
"Velocity bleed must be a finite positive number in range [0, 1]."
1167 if(json.find(
"velocity_cutoff") != json.end()) {
1168 physics.mVelocityCutoff = json.at(
"velocity_cutoff");
1171 &&
isFinite(physics.mVelocityCutoff)
1173 &&
"Velocity cutoff must be a finite non-negative number"
1177 if(json.find(
"angular_velocity") != json.end()) {
1178 physics.mAngularVelocity = glm::vec3 {
1179 json.at(
"angular_velocity")[0],
1180 json.at(
"angular_velocity")[1],
1181 json.at(
"angular_velocity")[2],
1183 assert(
isNumber(physics.mAngularVelocity) &&
isFinite(physics.mAngularVelocity) &&
"Angular velocity must be sensible");
1185 if(json.find(
"angular_velocity_bleed") != json.end()) {
1186 physics.mVelocityBleedAngular = json.at(
"angular_velocity_bleed");
1188 isNumber(physics.mVelocityBleedAngular)
1189 && physics.mVelocityBleedAngular >= 0.f
1190 && physics.mVelocityBleedAngular <= 1.f
1191 &&
"Velocity bleed must be a finite positive number in range [0, 1]."
1194 if(json.find(
"angular_velocity_cutoff") != json.end()) {
1195 physics.mVelocityCutoffAngular = json.at(
"angular_velocity_cutoff");
1197 isNumber(physics.mVelocityCutoffAngular)
1198 &&
isFinite(physics.mVelocityCutoffAngular)
1200 &&
"Velocity cutoff must be a finite positive number"
1204 if(json.find(
"force") != json.end()) {
1205 physics.mForce = glm::vec3 {
1206 json.at(
"force")[0],
1207 json.at(
"force")[1],
1208 json.at(
"force")[2],
1210 assert(
isNumber(physics.mForce) &&
isFinite(physics.mForce) &&
"Force must be sensible");
1213 if(json.find(
"torque") != json.end()) {
1214 physics.mForce = glm::vec3 {
1215 json.at(
"torque")[0],
1216 json.at(
"torque")[1],
1217 json.at(
"torque")[2],
1219 assert(
isNumber(physics.mTorque) &&
isFinite(physics.mTorque) &&
"Torque must be sensible");
1222 if(json.find(
"coefficient_friction_static") != json.end()) {
1223 physics.mCoefficientFrictionStatic = json.at(
"coefficient_friction_static");
1224 assert(physics.mCoefficientFrictionStatic >= 0.f &&
"Coefficient friction must be non-negative");
1227 if(json.find(
"coefficient_friction_dynamic") != json.end()) {
1228 physics.mCoefficientFrictionDynamic = json.at(
"coefficient_friction_dynamic");
1229 assert(physics.mCoefficientFrictionDynamic >= 0.f &&
"Coefficient friction must be non-negative");
1232 if(json.find(
"coefficient_restitution") != json.end()) {
1233 physics.setCoefficientRestitution(json.at(
"coefficient_restitution"));
1237 inline void to_json(
1238 nlohmann::json& json,
1241 const float mass { physics.getMass() };
1242 std::vector<PhysicsState::CollisionResponse> collisionResponse {};
1251 mass != std::numeric_limits<float>::max()?
1252 nlohmann::json::object({
"mass", mass }):
1253 nlohmann::json::object({
"mass",
"infinity" }),
1254 {
"mode", physics.getMode() },
1255 {
"collision_response", collisionResponse },
1256 {
"coefficient_friction_static", physics.mCoefficientFrictionStatic },
1257 {
"coefficient_friction_dynamic", physics.mCoefficientFrictionDynamic },
1258 {
"coefficient_restitution", physics.mCoefficientRestitution },
1259 {
"velocity_bleed", physics.mVelocityBleed },
1260 {
"angular_velocity_bleed", physics.mVelocityBleedAngular },
1261 {
"velocity_cutoff", physics.mVelocityCutoff },
1262 {
"velocity_cutoff_angular", physics.mVelocityCutoffAngular },
1266 template <u
int8_t LagrangeCount>
1271 template <u
int8_t LagrangeCount>
1276 template <u
int8_t LagrangeCount>
1282 template <u
int8_t LagrangeCount>
1284 resetLagrange(std::make_integer_sequence<uint8_t, LagrangeCount>());
1287 template<u
int8_t LagrangeCount>
1288 template<uint8_t ...indices>
1290 ((mLagrangeMultipliers[indices] = mLagrangeDeltas[indices] = 0.f), ...);
1293 template<
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
1298 template <
typename TConstraint,
1307 static_cast<TConstraint&
>(*this).
setParameter(participant, parameter);
1310 template <
typename TConstraint,
1319 return static_cast<TConstraint&
>(*this).
getParameter(participant);
1323 template<
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
1329 template<
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
1334 template <
typename TConstraint,
1343 static_cast<TConstraint&
>(*this).
setConfig(config);
1346 template <
typename TConstraint,
1355 return static_cast<TConstraint&
>(*this).
getConfig();
1358 template<
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
1363 template <
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
1368 template <
typename TConfig,
typename TParameter, u
int8_t LagrangeCount>
1370 for(
auto i { 0 }; i < constraintParameters.size(); ++i) {
1371 setParameter(i, constraintParameters[i]);
Base class for constraints.
Definition types.hpp:506
void setConfig(const typename TConstraint::Config &config)
Sets the configuration of a constraint.
Definition types.hpp:1342
TConstraint::Config getConfig() const
Gets the configuration of a constraint.
Definition types.hpp:1354
TConstraint::Parameter getParameter(ParticipantID participant) const
Gets a parameter associated with a particular constraint participant.
Definition types.hpp:1318
virtual void applyConstraintVelocity(const ParticipantTable &states, float substepSeconds)
Applies velocity-based constraint to current set of bounds and physics states.
Definition types.hpp:562
BaseConstraint(float compliance)
Initializes this constraint.
Definition types.hpp:524
virtual void resetLagrange()
Resets all lagrange multipliers, preparing them for a new sequence of constraint solve substeps.
Definition types.hpp:572
float mCompliance
Value greater than equal to zero, inverse of the physical stiffness of this constraint.
Definition types.hpp:517
void setCompliance(float newCompliance)
Sets the compliance value for this constraint.
Definition types.cpp:42
void setParameter(ParticipantID participant, const typename TConstraint::Parameter ¶meter)
Sets a parameter belonging to a particular constraint participant.
Definition types.hpp:1306
virtual void applyConstraintPosition(const ParticipantTable &states, float substepSeconds)
Applies positional constraint to current set of bounds and physics states.
Definition types.hpp:550
float getCompliance() const
Gets the current compliance value for this constraint.
Definition types.cpp:47
The velocity constraint responsible for applying a velocity-dependent damping force on all dynamic ob...
Definition types.hpp:987
void applyConstraintVelocity(const ParticipantTable &states, float substepSeconds) override
Slow down dynamic objects moving at a constant speed so that they eventually come to a stop.
Definition types.cpp:608
Constraint where the distance between a pair of points, one from each participant,...
Definition types.hpp:1109
void applyConstraintPosition(const ParticipantTable &states, float substepSeconds)
Applies positional constraint to current set of bounds and physics states.
Definition types.cpp:740
Subclass implementation for any constraint which takes data of type TParameter.
Definition types.hpp:716
const std::unordered_map< BaseConstraint::ParticipantID, TParameter > & getParameters() const
Returns all parameters known to this constraint.
Definition types.hpp:1364
ConstraintParametrized(const TConfig &config, const std::vector< TParameter > &constraintParameters, float compliance)
Initializes this constraint with some initial compliance value and constraint parameters.
Definition types.hpp:1369
TParameter getParameter(BaseConstraint::ParticipantID participant) const
Gets parameter belonging to a particular constraint participant.
Definition types.hpp:769
TConfig mConfig
The configuration of the constraint as a whole, specific to this constraint.
Definition types.hpp:730
void setParameter(BaseConstraint::ParticipantID participant, const TParameter ¶meter)
Adds a parameter for this constraint.
Definition types.hpp:1294
std::unordered_map< BaseConstraint::ParticipantID, TParameter > mParameters
A set of parameters associated with each entity.
Definition types.hpp:724
void setConfig(const TConfig &config)
Sets configuration for this constraint.
Definition types.hpp:1324
void removeParameter(BaseConstraint::ParticipantID participant)
Removes a parameter belonging to a particular constraint participant.
Definition types.hpp:1359
TConfig getConfig() const
Gets the current configuration of this constraint.
Definition types.hpp:1330
Restricts angle between 2 vectors from 2 participants around an axis defined relative to participant ...
Definition types.hpp:1098
void applyConstraintPosition(const ParticipantTable &states, float substepSeconds)
Applies positional constraint to current set of bounds and physics states.
Definition types.cpp:659
Any constraint storing LagrangeCount correction multipliers.
Definition types.hpp:646
void applyLagrangeDelta(float delta, uint8_t index)
Adds a delta to a lagrange value located at index.
Definition types.hpp:1277
const std::array< float, LagrangeCount > & getLagrangeDelta() const
Gets the latest lagrange delta applied to a constraint.
Definition types.hpp:1272
const std::array< float, LagrangeCount > & getLagrange() const
Gets the current Lagrange multiplier values for this constraint.
Definition types.hpp:1267
Constraint(float compliance)
Initializes this constraint with some initial compliance value.
Definition types.hpp:678
void resetLagrange(std::integer_sequence< uint8_t, ints... > index)
Private implementation for each lagrange multiplier index in need of a reset.
std::array< float, LagrangeCount > mLagrangeDeltas
The last delta applied to the Lagrange multiplier for this constraint.
Definition types.hpp:671
void resetLagrange() override
Sets all lagrange multipliers to 0 in preparation for the next physics update.
Definition types.hpp:1283
std::array< float, LagrangeCount > mLagrangeMultipliers
The Lagrange multiplier, computed every substep since the start of the physics simulation till the cu...
Definition types.hpp:665
bool isPositiveStrict(float number)
Tests whether a number is strictly positive.
Definition util.hpp:71
bool isNumber(float number)
Tests whether a float is really a number (as opposed to a special error representation).
Definition util.hpp:92
bool isNonNegative(float number)
Tests whether a number is non-negative.
Definition util.hpp:113
float squareDistance(const glm::vec3 &vector)
Returns the square of the length of a 3 component vector.
Definition util.hpp:35
bool isFinite(float number)
Tests whether a given number is finite.
Definition util.hpp:47
bool isSensible(const glm::mat3 &matrix)
Determines whether a particular matrix is valid and finite.
Definition math.cpp:775
CollisionResponse
Defines how the object this component is attached to responds to collisions.
Definition types.hpp:190
float computeGeneralizedInverseMassPositional(const ObjectBounds &object, const PhysicsState &physics, const glm::vec3 &correctionPoint, const glm::vec3 &correctionGradient)
Computes the generalized inverse mass used for positional corrections applied by constraints.
Definition types.cpp:821
glm::mat3 computeInertiaRotationalWorld(const glm::vec3 &rotationalInertiaLocal, const glm::quat &orientation)
Returns an objects rotation tensor in the global frame given its tensor in the local frame according ...
ObjectBounds applyImpulseObject(ObjectBounds object, const PhysicsState &physics, const glm::vec3 &impulsePositional, const glm::vec3 &impulsePoint)
Returns object bounds in state it would be post application of a positional impulse.
Definition types.cpp:854
float computeGeneralizedInverseMassRotational(const ObjectBounds &object, const PhysicsState &physics, const glm::vec3 &correctionRotational)
Computes the generalized inverse mass used by constraints to apply strictly rotational corrections.
Definition types.cpp:841
Mode
Defines how the object this component is attached to responds to physics updates.
Definition types.hpp:152
PhysicsState applyImpulsePhysics(const ObjectBounds &object, PhysicsState physics, const glm::vec3 &impulsePositional, const glm::vec3 &impulsePoint)
Returns new physics state after application of global impulse.
Definition types.cpp:878
@ COLLISION_SIGNAL
Whether this object's collision events should be reported (via signal).
Definition types.hpp:201
@ COLLISION_SEPARATE
Whether this object should be separated from the object it collides with.
Definition types.hpp:195
@ MODE_KINEMATIC
Trait indicating that this object will undergo position and orientation updates according to its tran...
Definition types.hpp:168
@ MODE_STATIC
Trait indicating that this object won't undergo any physics system updates whatsoever.
Definition types.hpp:174
@ MODE_DYNAMIC
Trait indicating that this object responds to external forces, including those set externally,...
Definition types.hpp:158
Namespace containing all class definitions and functions related to the ToyMaker engine.
Definition application.hpp:26
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 collection of values defining an orientation or position constraint for a single degree of freedom.
Definition types.hpp:1012
glm::vec3 mAxis
A non-zero vector relative to participant 0 along or about which rotation or position is constrained ...
Definition types.hpp:1018
bool isSensible(bool isRotation=false) const
Tests invariants for the constraint this block of data is associated with.
Definition types.hpp:1050
float mBoundUpper
The highest permissible angle between the pair of vectors from participant 0 and 1.
Definition types.hpp:1038
bool isActive
Whether the constraint associated with this configuration is in effect.
Definition types.hpp:1044
float mBoundLower
The lowest permissible angle or distance between the pair of vectors or points from participants 0 an...
Definition types.hpp:1028
Parameters defining a body participating in a 2-body constraint.
Definition types.hpp:1070
glm::quat mRotateToLocal
The rotation taking the parameter from constraint space to object-local space.
Definition types.hpp:1075
glm::vec3 mVector
The constrained vector representing a position for a distance constraints, and a direction for a rota...
Definition types.hpp:1082
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
float mVelocityCutoff
The linear velocity below which the object's velocity is set to 0, bringing it to a stop.
Definition types.hpp:309
glm::vec3 mAngularVelocity
The angular velocity of this object.
Definition types.hpp:251
Mode getMode() const
Returns the physics type associated with this object.
Definition types.hpp:415
void applyForceGlobal(const glm::vec3 &force, const glm::vec3 &atPosition, const ObjectBounds &bounds)
Applies a force force at position atPosition, updating the torque and central force of an object whos...
Definition types.cpp:18
float mCoefficientFrictionStatic
The friction coefficient of the force that prevents relative motion between the surface of two object...
Definition types.hpp:273
bool separatesOnCollision() const
Whether this object is configured to separate from another object it collides with.
Definition types.hpp:454
static const Traits MaskCollisionResponse
Mask used to retrieve the section of an object's physics traits that indicate its collision response ...
Definition types.hpp:209
Traits mTraits
Defines a set of flags that determines how this object responds to physics updates.
Definition types.hpp:321
void setMass(float mass)
Sets the mass of this object.
Definition types.hpp:362
void setCollisionResponse(CollisionResponse response)
Sets a flag related to this object's collision response behaviour.
Definition types.hpp:475
void unsetCollisionResponse(CollisionResponse response)
Unsets a flag related to this object's collision response behaviour.
Definition types.hpp:483
void setRotationalInertia(const glm::vec3 &rotationalInertia)
Sets the rotational inertia for this object along each axis in the object's local frame.
Definition types.hpp:387
glm::vec3 mTorque
Proportional to sum of all forces acting perpendicular to the vector going from the point at which th...
Definition types.hpp:235
void applyForceLocal(const glm::vec3 &force, const glm::vec3 &atPosition, const ObjectBounds &bounds)
Applies a force force at position atPosition, updating the torque and central force of an object whos...
Definition types.cpp:10
float mVelocityCutoffAngular
The angular velocity below which the object's velocity is set to 0, bringing it to a stop.
Definition types.hpp:315
void setCoefficientRestitution(float newCoefficient)
Sets the coefficient of restitution for this object.
Definition types.hpp:403
bool signalsOnCollision() const
Whether this object is configured to report when it makes contact with another object.
Definition types.hpp:467
glm::vec3 mForce
The sum of all the forces acting on this object's center of mass, causing it to move through space.
Definition types.hpp:225
void setMode(Mode mode)
Sets the physics type associated with this object.
Definition types.hpp:433
float mMassInverse
The inverse of this object's mass.
Definition types.hpp:266
glm::vec3 mVelocity
The velocity of this object.
Definition types.hpp:243
float mCoefficientRestitution
The fraction of the net kinetic energy prior to a collision retained by a pair of objects after the c...
Definition types.hpp:289
glm::vec3 getRotationalInertia() const
Gets the rotational inertia for this object along each axis in the object's local frame.
Definition types.hpp:375
float mCoefficientFrictionDynamic
The friction coefficient of the force that hinders motion between the surface of two objects when the...
Definition types.hpp:280
glm::vec3 mRotationalInertiaInverse
The inverse of this object's resistance to rotational change.
Definition types.hpp:260
float mVelocityBleedAngular
The approximate fraction (as a number in range [0, 1]) of angular velocity lost by a rotating object ...
Definition types.hpp:303
static std::string getComponentTypeName()
Fetches the component type string associated with this class.
Definition types.hpp:216
float getMass() const
Gets the mass of this object.
Definition types.hpp:351
static const Traits MaskMode
Mask used to retrieve the section of an object's physics traits that indicate its update mode.
Definition types.hpp:182
float mVelocityBleed
The approximate fraction (as a number in range [0, 1]) of velocity lost by a moving object not experi...
Definition types.hpp:296