Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add friction and restitution on penetration constraint solving #1277

Merged
merged 4 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Raycasting, collisions between rays and box/capsule colliders (#225, **@diogomsmiranda**).
- Change speed of the debug-camera using Tab and LShift, positive and negative respectively (#1159, **@diogomsmiranda**)
- Console plugin (#875, **@Scarface1809**).
- Friction calculation for penetration constraint (#1244, **@fallenatlas**).
- Bounciness calculation for penetration constraint (#1275, **@fallenatlas**).

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@ namespace cubos::engine
CUBOS_REFLECT;

glm::vec3 position = {0.0F, 0.0F, 0.0F}; ///< Accumulated position correction.
float impulse = 0.0F; ///< Accumulated impulse.
};
} // namespace cubos::engine
3 changes: 0 additions & 3 deletions engine/samples/complex_physics/assets/scenes/red_cube.cubos
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
"entities": {
"cube": {
"cubos::engine::AccumulatedCorrection": {
"position": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"impulse": 0.0
},
"cubos::engine::BoxCollisionShape": {
"x": 0.5,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@
"entities": {
"cube": {
"cubos::engine::AccumulatedCorrection": {
"position": {
"x": 0.0,
"y": 0.0,
"z": 0.0
},
"impulse": 0.0
},
"cubos::engine::BoxCollisionShape": {
"x": 0.5,
Expand Down
7 changes: 7 additions & 0 deletions engine/src/physics/constraints/penetration_constraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
.withField("penetration", &PenetrationConstraint::penetration)
.withField("normal", &PenetrationConstraint::normal)
.withField("normalMass", &PenetrationConstraint::normalMass)
.withField("normalImpulse", &PenetrationConstraint::normalImpulse)
.withField("friction", &PenetrationConstraint::friction)
.withField("frictionMass", &PenetrationConstraint::frictionMass)
.withField("frictionImpulse1", &PenetrationConstraint::frictionImpulse1)
.withField("frictionImpulse2", &PenetrationConstraint::frictionImpulse2)
.withField("restitution", &PenetrationConstraint::restitution)
.withField("relativeVelocity", &PenetrationConstraint::relativeVelocity)

Check warning on line 23 in engine/src/physics/constraints/penetration_constraint.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/constraints/penetration_constraint.cpp#L17-L23

Added lines #L17 - L23 were not covered by tests
.withField("biasCoefficient", &PenetrationConstraint::biasCoefficient)
.withField("impulseCoefficient", &PenetrationConstraint::impulseCoefficient)
.withField("massCoefficient", &PenetrationConstraint::massCoefficient)
Expand Down
14 changes: 13 additions & 1 deletion engine/src/physics/constraints/penetration_constraint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,19 @@ namespace cubos::engine
float penetration; ///< Penetration depth of the collision.
glm::vec3 normal; ///< Normal of contact on the surface of the entity.

float normalMass;
// separation
float normalMass; ///< Mass to use for normal impulse calculation.
float normalImpulse; ///< Accumulated impulse for separation.

// friction
float friction; ///< Friction of the constraint.
float frictionMass; ///< Mass to use for friction impulse calculation.
float frictionImpulse1; ///< Accumulated impulse for friction along the first tangent.
float frictionImpulse2; ///< Accumulated impulse for friction along the second tangent.

// restitution
float restitution; ///< Restitution coefficient of the constraint.
float relativeVelocity; ///< Relative velocity for computing restitution.

// soft constraint
float biasCoefficient;
Expand Down
1 change: 0 additions & 1 deletion engine/src/physics/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ CUBOS_REFLECT_IMPL(AccumulatedCorrection)
{
return cubos::core::ecs::TypeBuilder<AccumulatedCorrection>("cubos::engine::AccumulatedCorrection")
.withField("position", &AccumulatedCorrection::position)
.withField("impulse", &AccumulatedCorrection::impulse)
.build();
}

Expand Down
2 changes: 1 addition & 1 deletion engine/src/physics/solver/integration/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ void cubos::engine::physicsIntegrationPlugin(Cubos& cubos)
{
continue;
}

position.vec += correction.position;
correction.position = glm::vec3(0.0F);
correction.impulse = 0.0F;
}
});

Expand Down
205 changes: 164 additions & 41 deletions engine/src/physics/solver/penetration_constraint/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,23 @@
CUBOS_DEFINE_TAG(cubos::engine::addPenetrationConstraintTag);
CUBOS_DEFINE_TAG(cubos::engine::penetrationConstraintSolveTag);
CUBOS_DEFINE_TAG(cubos::engine::penetrationConstraintSolveRelaxTag);
CUBOS_DEFINE_TAG(cubos::engine::penetrationConstraintRestitutionTag);
CUBOS_DEFINE_TAG(cubos::engine::penetrationConstraintCleanTag);

void getPlaneSpace(const glm::vec3& n, glm::vec3& tangent1, glm::vec3& tangent2)

Check warning on line 22 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L22

Added line #L22 was not covered by tests
{
if (glm::abs(n.z) > (1.0F / glm::sqrt(2.0F)))

Check warning on line 24 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L24

Added line #L24 was not covered by tests
{
tangent1 = glm::normalize(glm::vec3(0.0F, -n.z, n.y));
tangent2 = glm::cross(n, tangent1);

Check warning on line 27 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L26-L27

Added lines #L26 - L27 were not covered by tests
}
else
{
tangent1 = glm::normalize(glm::vec3(-n.y, n.x, 0.0F));
tangent2 = glm::cross(n, tangent1);

Check warning on line 32 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L31-L32

Added lines #L31 - L32 were not covered by tests
}
}

void solvePenetrationConstraint(Query<Entity, const Mass&, AccumulatedCorrection&, Velocity&, PenetrationConstraint&,
Entity, const Mass&, AccumulatedCorrection&, Velocity&>
query,
Expand All @@ -28,37 +43,31 @@

float subDeltaTime = fixedDeltaTime.value / (float)substeps.value;

glm::vec3 v1;
glm::vec3 v2;
glm::vec3 v1 = velocity1.vec;
glm::vec3 v2 = velocity2.vec;

Check warning on line 47 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L46-L47

Added lines #L46 - L47 were not covered by tests

// for each contact point, for now its for each entity
for (int i = 0; i < 2; i++)
// for each contact point in the future, since we have particles now we only need to do it once
{
float totalImpulse = i == 0 ? correction1.impulse : correction2.impulse;
float totalImpulse = constraint.normalImpulse;

Check warning on line 51 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L51

Added line #L51 was not covered by tests

// compute current penatration
float penetration = constraint.penetration;
// compute current penetration
float penetration = -constraint.penetration;

Check warning on line 54 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L54

Added line #L54 was not covered by tests

if (ent1 == constraint.entity)
{
glm::vec3 deltaPenetration = correction2.position - correction1.position;
penetration += glm::dot(deltaPenetration, constraint.normal);
}
else
glm::vec3 deltaPenetration = correction2.position - correction1.position;

Check warning on line 56 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L56

Added line #L56 was not covered by tests

if (ent1 != constraint.entity)

Check warning on line 58 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L58

Added line #L58 was not covered by tests
{
glm::vec3 deltaPenetration = correction1.position - correction2.position;
penetration += glm::dot(deltaPenetration, constraint.normal);
deltaPenetration *= -1.0F;

Check warning on line 60 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L60

Added line #L60 was not covered by tests
}

// penetration is positive but we need negative value for separation
luishfonseca marked this conversation as resolved.
Show resolved Hide resolved
penetration = -penetration;
penetration += glm::dot(deltaPenetration, constraint.normal);

Check warning on line 63 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L63

Added line #L63 was not covered by tests

float bias = 0.0F;
float massScale = 1.0F;
float impulseScale = 0.0F;
if (penetration > 0.0F)
{
bias = penetration * 1.0F / subDeltaTime;
bias = 0.2F * penetration * (1.0F / subDeltaTime);

Check warning on line 70 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L70

Added line #L70 was not covered by tests
luishfonseca marked this conversation as resolved.
Show resolved Hide resolved
}
else if (useBias)
{
Expand All @@ -68,47 +77,90 @@
}

// Relative velocity at contact
glm::vec3 vr2;
glm::vec3 vr1;
if (ent1 == constraint.entity)
{
vr2 = velocity2.vec;
vr1 = velocity1.vec;
}
else
glm::vec3 vr = velocity2.vec - velocity1.vec;

Check warning on line 80 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L80

Added line #L80 was not covered by tests

if (ent1 != constraint.entity)

Check warning on line 82 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L82

Added line #L82 was not covered by tests
{
vr2 = velocity1.vec;
vr1 = velocity2.vec;
vr *= -1.0F;

Check warning on line 84 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L84

Added line #L84 was not covered by tests
}

float vn = glm::dot(vr2 - vr1, constraint.normal);
float vn = glm::dot(vr, constraint.normal);

Check warning on line 87 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L87

Added line #L87 was not covered by tests

// Compute normal impulse
float impulse = -constraint.normalMass * massScale * (vn + bias) - impulseScale * totalImpulse;

// Clamp the accumulated impulse
float newImpulse = glm::max(totalImpulse + impulse, 0.0F);
impulse = newImpulse - totalImpulse;
if (i == 0)
constraint.normalImpulse = newImpulse;

Check warning on line 95 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L95

Added line #L95 was not covered by tests

glm::vec3 p = impulse * constraint.normal;

Check warning on line 97 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L97

Added line #L97 was not covered by tests

if (ent1 != constraint.entity)

Check warning on line 99 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L99

Added line #L99 was not covered by tests
{
correction1.impulse = newImpulse;
p *= -1.0F;

Check warning on line 101 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L101

Added line #L101 was not covered by tests
}
else

v1 = velocity1.vec - p * mass1.inverseMass;
v2 = velocity2.vec + p * mass2.inverseMass;

Check warning on line 105 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L104-L105

Added lines #L104 - L105 were not covered by tests
}

// Friction
// for each contact point in the future, since we have particles now we only need to do it once
{
float normalImpulse = constraint.normalImpulse;
float frictionImpulse1 = constraint.frictionImpulse1;
float frictionImpulse2 = constraint.frictionImpulse2;

Check warning on line 113 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L111-L113

Added lines #L111 - L113 were not covered by tests

// Relative velocity at contact
glm::vec3 vr = velocity2.vec - velocity1.vec;

Check warning on line 116 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L116

Added line #L116 was not covered by tests

if (ent1 != constraint.entity)

Check warning on line 118 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L118

Added line #L118 was not covered by tests
{
correction2.impulse = newImpulse;
vr *= -1.0F;

Check warning on line 120 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L120

Added line #L120 was not covered by tests
}

glm::vec3 p = constraint.normal * impulse;
if (ent1 == constraint.entity)
glm::vec3 tangent1 = vr - glm::dot(vr, constraint.normal) * constraint.normal;

Check warning on line 123 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L123

Added line #L123 was not covered by tests
glm::vec3 tangent2;
float tangentLenSq = glm::length2(tangent1);
if (tangentLenSq > 1e-6 * 1e-6)

Check warning on line 126 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L125-L126

Added lines #L125 - L126 were not covered by tests
fallenatlas marked this conversation as resolved.
Show resolved Hide resolved
{
v1 = velocity1.vec - p * mass1.inverseMass;
v2 = velocity2.vec + p * mass2.inverseMass;
tangent1 = glm::normalize(tangent1);
tangent2 = glm::cross(constraint.normal, tangent1);

Check warning on line 129 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L128-L129

Added lines #L128 - L129 were not covered by tests
}
else
{
v1 = velocity1.vec + p * mass1.inverseMass;
v2 = velocity2.vec - p * mass2.inverseMass;
// if there is no tangent in relation that can be obtained from vr calculate a basis for the tangent
// plane.
getPlaneSpace(constraint.normal, tangent1, tangent2);

Check warning on line 135 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L135

Added line #L135 was not covered by tests
}

float vn1 = glm::dot(vr, tangent1);
float vn2 = glm::dot(vr, tangent2);

Check warning on line 139 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L138-L139

Added lines #L138 - L139 were not covered by tests

// Compute friction force
float impulse1 = -constraint.frictionMass * vn1;
float impulse2 = -constraint.frictionMass * vn2;

Check warning on line 143 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L142-L143

Added lines #L142 - L143 were not covered by tests

// Clamp the accumulated force
float maxFriction = constraint.friction * normalImpulse;
float newImpulse1 = glm::clamp(frictionImpulse1 + impulse1, -maxFriction, maxFriction);
float newImpulse2 = glm::clamp(frictionImpulse2 + impulse2, -maxFriction, maxFriction);
impulse1 = newImpulse1 - frictionImpulse1;
impulse2 = newImpulse2 - frictionImpulse2;
constraint.frictionImpulse1 = newImpulse1;
constraint.frictionImpulse2 = newImpulse2;

Check warning on line 152 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L146-L152

Added lines #L146 - L152 were not covered by tests

// Apply contact impulse
glm::vec3 p = impulse1 * tangent1 + impulse2 * tangent2;

Check warning on line 155 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L155

Added line #L155 was not covered by tests

if (ent1 != constraint.entity)

Check warning on line 157 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L157

Added line #L157 was not covered by tests
{
p *= -1.0F;

Check warning on line 159 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L159

Added line #L159 was not covered by tests
}

v1 -= p * mass1.inverseMass;
v2 += p * mass2.inverseMass;

Check warning on line 163 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L162-L163

Added lines #L162 - L163 were not covered by tests
}

velocity1.vec = v1;
Expand All @@ -129,6 +181,7 @@
cubos.tag(addPenetrationConstraintTag);
cubos.tag(penetrationConstraintSolveTag);
cubos.tag(penetrationConstraintSolveRelaxTag);
cubos.tag(penetrationConstraintRestitutionTag);

Check warning on line 184 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L184

Added line #L184 was not covered by tests
cubos.tag(penetrationConstraintCleanTag);

cubos.system("solve contacts bias")
Expand All @@ -149,19 +202,82 @@
const FixedDeltaTime& fixedDeltaTime,
const Substeps& substeps) { solvePenetrationConstraint(query, fixedDeltaTime, substeps, false); });

cubos.system("add restitution")
.tagged(penetrationConstraintRestitutionTag)
.after(penetrationConstraintSolveRelaxTag)
.before(physicsFinalizePositionTag)
.tagged(fixedStepTag)
.call([](Query<Entity, const Mass&, AccumulatedCorrection&, Velocity&, PenetrationConstraint&, Entity,

Check warning on line 210 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L205-L210

Added lines #L205 - L210 were not covered by tests
const Mass&, AccumulatedCorrection&, Velocity&>
query) {
for (auto [ent1, mass1, correction1, velocity1, constraint, ent2, mass2, correction2, velocity2] : query)

Check warning on line 213 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L213

Added line #L213 was not covered by tests
{
if (constraint.restitution == 0.0F)

Check warning on line 215 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L215

Added line #L215 was not covered by tests
{
continue;

Check warning on line 217 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L217

Added line #L217 was not covered by tests
}

if (constraint.relativeVelocity > -0.1F || constraint.normalImpulse == 0.0F)

Check warning on line 220 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L220

Added line #L220 was not covered by tests
{
continue;

Check warning on line 222 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L222

Added line #L222 was not covered by tests
}

// Relative normal velocity at contact
glm::vec3 vr = velocity2.vec - velocity1.vec;

Check warning on line 226 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L226

Added line #L226 was not covered by tests

if (ent1 != constraint.entity)

Check warning on line 228 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L228

Added line #L228 was not covered by tests
{
vr *= -1.0F;

Check warning on line 230 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L230

Added line #L230 was not covered by tests
}
float vn = glm::dot(vr, constraint.normal);

Check warning on line 232 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L232

Added line #L232 was not covered by tests

// compute normal impulse
float impulse = -constraint.normalMass * (vn + constraint.restitution * constraint.relativeVelocity);

Check warning on line 235 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L235

Added line #L235 was not covered by tests

// Clamp the accumulated impulse
float newImpulse = glm::max(constraint.normalImpulse + impulse, 0.0F);
impulse = newImpulse - constraint.normalImpulse;
constraint.normalImpulse = newImpulse;

Check warning on line 240 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L238-L240

Added lines #L238 - L240 were not covered by tests

// Apply impulse
glm::vec3 p = constraint.normal * impulse;
velocity1.vec = velocity1.vec - p * mass1.inverseMass;
velocity2.vec = velocity2.vec + p * mass2.inverseMass;

Check warning on line 245 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L243-L245

Added lines #L243 - L245 were not covered by tests
}
});

Check warning on line 247 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L247

Added line #L247 was not covered by tests

cubos.system("add penetration constraint pair")
.tagged(addPenetrationConstraintTag)
.tagged(physicsPrepareSolveTag)
.call([](Commands cmds, Query<Entity, const Mass&, const CollidingWith&, Entity, const Mass&> query,
.call([](Commands cmds,

Check warning on line 252 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L252

Added line #L252 was not covered by tests
Query<Entity, const Mass&, const Velocity&, const CollidingWith&, Entity, const Mass&, const Velocity&>
query,
const FixedDeltaTime& fixedDeltaTime, const Substeps& substeps) {
float subDeltaTime = fixedDeltaTime.value / (float)substeps.value;
float contactHertz = glm::min(30.0F, 0.25F * (1.0F / subDeltaTime));

for (auto [ent1, mass1, collidingWith, ent2, mass2] : query)
for (auto [ent1, mass1, velocity1, collidingWith, ent2, mass2, velocity2] : query)

Check warning on line 259 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L259

Added line #L259 was not covered by tests
{
float kNormal = mass1.inverseMass + mass2.inverseMass;
float normalMass = kNormal > 0.0F ? 1.0F / kNormal : 0.0F;

// friction mass
float kFriction = mass1.inverseMass + mass2.inverseMass;
float frictionMass = kFriction > 0.0F ? 1.0F / kFriction : 0.0F;

Check warning on line 266 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L265-L266

Added lines #L265 - L266 were not covered by tests

// determine friction (set to predefined value for now)
float friction = 0.01F;

Check warning on line 269 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L269

Added line #L269 was not covered by tests

// determine restitution (set to predefined value for now)
float restitution = 1.0F;
glm::vec3 vr = velocity2.vec - velocity1.vec;

Check warning on line 273 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L272-L273

Added lines #L272 - L273 were not covered by tests

if (ent1 != collidingWith.entity)

Check warning on line 275 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L275

Added line #L275 was not covered by tests
{
vr *= -1.0F;

Check warning on line 277 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L277

Added line #L277 was not covered by tests
}
float relativeVelocity = glm::dot(vr, collidingWith.normal);

Check warning on line 279 in engine/src/physics/solver/penetration_constraint/plugin.cpp

View check run for this annotation

Codecov / codecov/patch

engine/src/physics/solver/penetration_constraint/plugin.cpp#L279

Added line #L279 was not covered by tests

// Soft contact
const float zeta = 10.0F;
float omega = 2.0F * glm::pi<float>() * contactHertz;
Expand All @@ -178,6 +294,13 @@
.penetration = collidingWith.penetration,
.normal = collidingWith.normal,
.normalMass = normalMass,
.normalImpulse = 0.0F,
.friction = friction,
.frictionMass = frictionMass,
.frictionImpulse1 = 0.0F,
.frictionImpulse2 = 0.0F,
.restitution = restitution,
.relativeVelocity = relativeVelocity,
.biasCoefficient = biasCoefficient,
.impulseCoefficient = impulseCoefficient,
.massCoefficient = massCoefficient});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace cubos::engine
extern Tag addPenetrationConstraintTag;
extern Tag penetrationConstraintCleanTag;
extern Tag penetrationConstraintSolveTag;
extern Tag penetrationConstraintRestitutionTag;
extern Tag penetrationConstraintSolveRelaxTag;

/// @brief Plugin entry function.
Expand Down
Loading