Add support for rolling resistance in the contact solver
This commit is contained in:
parent
10549796c8
commit
3e98ab2282
|
@ -119,6 +119,9 @@ class ContactManifold {
|
||||||
/// Twist friction constraint accumulated impulse
|
/// Twist friction constraint accumulated impulse
|
||||||
decimal mFrictionTwistImpulse;
|
decimal mFrictionTwistImpulse;
|
||||||
|
|
||||||
|
/// Accumulated rolling resistance impulse
|
||||||
|
Vector3 mRollingResistanceImpulse;
|
||||||
|
|
||||||
/// True if the contact manifold has already been added into an island
|
/// True if the contact manifold has already been added into an island
|
||||||
bool mIsAlreadyInIsland;
|
bool mIsAlreadyInIsland;
|
||||||
|
|
||||||
|
@ -216,6 +219,9 @@ class ContactManifold {
|
||||||
/// Set the friction twist accumulated impulse
|
/// Set the friction twist accumulated impulse
|
||||||
void setFrictionTwistImpulse(decimal frictionTwistImpulse);
|
void setFrictionTwistImpulse(decimal frictionTwistImpulse);
|
||||||
|
|
||||||
|
/// Set the accumulated rolling resistance impulse
|
||||||
|
void setRollingResistanceImpulse(const Vector3& rollingResistanceImpulse);
|
||||||
|
|
||||||
/// Return a contact point of the manifold
|
/// Return a contact point of the manifold
|
||||||
ContactPoint* getContactPoint(uint index) const;
|
ContactPoint* getContactPoint(uint index) const;
|
||||||
|
|
||||||
|
@ -312,6 +318,11 @@ inline void ContactManifold::setFrictionTwistImpulse(decimal frictionTwistImpuls
|
||||||
mFrictionTwistImpulse = frictionTwistImpulse;
|
mFrictionTwistImpulse = frictionTwistImpulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the accumulated rolling resistance impulse
|
||||||
|
inline void ContactManifold::setRollingResistanceImpulse(const Vector3& rollingResistanceImpulse) {
|
||||||
|
mRollingResistanceImpulse = rollingResistanceImpulse;
|
||||||
|
}
|
||||||
|
|
||||||
// Return a contact point of the manifold
|
// Return a contact point of the manifold
|
||||||
inline ContactPoint* ContactManifold::getContactPoint(uint index) const {
|
inline ContactPoint* ContactManifold::getContactPoint(uint index) const {
|
||||||
assert(index >= 0 && index < mNbContactPoints);
|
assert(index >= 0 && index < mNbContactPoints);
|
||||||
|
|
|
@ -94,6 +94,9 @@ const decimal DEFAULT_FRICTION_COEFFICIENT = decimal(0.3);
|
||||||
/// Default bounciness factor for a rigid body
|
/// Default bounciness factor for a rigid body
|
||||||
const decimal DEFAULT_BOUNCINESS = decimal(0.5);
|
const decimal DEFAULT_BOUNCINESS = decimal(0.5);
|
||||||
|
|
||||||
|
/// Default rolling resistance
|
||||||
|
const decimal DEFAULT_ROLLING_RESISTANCE = decimal(0.0);
|
||||||
|
|
||||||
/// True if the spleeping technique is enabled
|
/// True if the spleeping technique is enabled
|
||||||
const bool SPLEEPING_ENABLED = true;
|
const bool SPLEEPING_ENABLED = true;
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,9 @@ class ContactPoint {
|
||||||
|
|
||||||
/// Cached second friction impulse
|
/// Cached second friction impulse
|
||||||
decimal mFrictionImpulse2;
|
decimal mFrictionImpulse2;
|
||||||
|
|
||||||
|
/// Cached rolling resistance impulse
|
||||||
|
Vector3 mRollingResistanceImpulse;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
|
@ -191,6 +194,9 @@ class ContactPoint {
|
||||||
/// Return the cached second friction impulse
|
/// Return the cached second friction impulse
|
||||||
decimal getFrictionImpulse2() const;
|
decimal getFrictionImpulse2() const;
|
||||||
|
|
||||||
|
/// Return the cached rolling resistance impulse
|
||||||
|
Vector3 getRollingResistanceImpulse() const;
|
||||||
|
|
||||||
/// Set the cached penetration impulse
|
/// Set the cached penetration impulse
|
||||||
void setPenetrationImpulse(decimal impulse);
|
void setPenetrationImpulse(decimal impulse);
|
||||||
|
|
||||||
|
@ -200,6 +206,9 @@ class ContactPoint {
|
||||||
/// Set the second cached friction impulse
|
/// Set the second cached friction impulse
|
||||||
void setFrictionImpulse2(decimal impulse);
|
void setFrictionImpulse2(decimal impulse);
|
||||||
|
|
||||||
|
/// Set the cached rolling resistance impulse
|
||||||
|
void setRollingResistanceImpulse(const Vector3& impulse);
|
||||||
|
|
||||||
/// Set the contact world point on body 1
|
/// Set the contact world point on body 1
|
||||||
void setWorldPointOnBody1(const Vector3& worldPoint);
|
void setWorldPointOnBody1(const Vector3& worldPoint);
|
||||||
|
|
||||||
|
@ -286,6 +295,11 @@ inline decimal ContactPoint::getFrictionImpulse2() const {
|
||||||
return mFrictionImpulse2;
|
return mFrictionImpulse2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the cached rolling resistance impulse
|
||||||
|
inline Vector3 ContactPoint::getRollingResistanceImpulse() const {
|
||||||
|
return mRollingResistanceImpulse;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the cached penetration impulse
|
// Set the cached penetration impulse
|
||||||
inline void ContactPoint::setPenetrationImpulse(decimal impulse) {
|
inline void ContactPoint::setPenetrationImpulse(decimal impulse) {
|
||||||
mPenetrationImpulse = impulse;
|
mPenetrationImpulse = impulse;
|
||||||
|
@ -301,6 +315,11 @@ inline void ContactPoint::setFrictionImpulse2(decimal impulse) {
|
||||||
mFrictionImpulse2 = impulse;
|
mFrictionImpulse2 = impulse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the cached rolling resistance impulse
|
||||||
|
inline void ContactPoint::setRollingResistanceImpulse(const Vector3& impulse) {
|
||||||
|
mRollingResistanceImpulse = impulse;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the contact world point on body 1
|
// Set the contact world point on body 1
|
||||||
inline void ContactPoint::setWorldPointOnBody1(const Vector3& worldPoint) {
|
inline void ContactPoint::setWorldPointOnBody1(const Vector3& worldPoint) {
|
||||||
mWorldPointOnBody1 = worldPoint;
|
mWorldPointOnBody1 = worldPoint;
|
||||||
|
|
|
@ -103,12 +103,15 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) {
|
||||||
internalManifold.nbContacts = externalManifold->getNbContactPoints();
|
internalManifold.nbContacts = externalManifold->getNbContactPoints();
|
||||||
internalManifold.restitutionFactor = computeMixedRestitutionFactor(body1, body2);
|
internalManifold.restitutionFactor = computeMixedRestitutionFactor(body1, body2);
|
||||||
internalManifold.frictionCoefficient = computeMixedFrictionCoefficient(body1, body2);
|
internalManifold.frictionCoefficient = computeMixedFrictionCoefficient(body1, body2);
|
||||||
|
internalManifold.rollingResistanceFactor = computeMixedRollingResistance(body1, body2);
|
||||||
internalManifold.externalContactManifold = externalManifold;
|
internalManifold.externalContactManifold = externalManifold;
|
||||||
|
internalManifold.isBody1DynamicType = body1->getType() == DYNAMIC;
|
||||||
|
internalManifold.isBody2DynamicType = body2->getType() == DYNAMIC;
|
||||||
|
|
||||||
// If we solve the friction constraints at the center of the contact manifold
|
// If we solve the friction constraints at the center of the contact manifold
|
||||||
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
||||||
internalManifold.frictionPointBody1 = Vector3(0.0, 0.0, 0.0);
|
internalManifold.frictionPointBody1 = Vector3::zero();
|
||||||
internalManifold.frictionPointBody2 = Vector3(0.0, 0.0, 0.0);
|
internalManifold.frictionPointBody2 = Vector3::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each contact point of the contact manifold
|
// For each contact point of the contact manifold
|
||||||
|
@ -135,6 +138,7 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) {
|
||||||
contactPoint.penetrationImpulse = 0.0;
|
contactPoint.penetrationImpulse = 0.0;
|
||||||
contactPoint.friction1Impulse = 0.0;
|
contactPoint.friction1Impulse = 0.0;
|
||||||
contactPoint.friction2Impulse = 0.0;
|
contactPoint.friction2Impulse = 0.0;
|
||||||
|
contactPoint.rollingResistanceImpulse = Vector3::zero();
|
||||||
|
|
||||||
// If we solve the friction constraints at the center of the contact manifold
|
// If we solve the friction constraints at the center of the contact manifold
|
||||||
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
||||||
|
@ -167,6 +171,7 @@ void ContactSolver::initializeForIsland(decimal dt, Island* island) {
|
||||||
internalManifold.friction1Impulse = 0.0;
|
internalManifold.friction1Impulse = 0.0;
|
||||||
internalManifold.friction2Impulse = 0.0;
|
internalManifold.friction2Impulse = 0.0;
|
||||||
internalManifold.frictionTwistImpulse = 0.0;
|
internalManifold.frictionTwistImpulse = 0.0;
|
||||||
|
internalManifold.rollingResistanceImpulse = Vector3(0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,6 +271,7 @@ void ContactSolver::initializeContactConstraints() {
|
||||||
contactPoint.penetrationImpulse = externalContact->getPenetrationImpulse();
|
contactPoint.penetrationImpulse = externalContact->getPenetrationImpulse();
|
||||||
contactPoint.friction1Impulse = externalContact->getFrictionImpulse1();
|
contactPoint.friction1Impulse = externalContact->getFrictionImpulse1();
|
||||||
contactPoint.friction2Impulse = externalContact->getFrictionImpulse2();
|
contactPoint.friction2Impulse = externalContact->getFrictionImpulse2();
|
||||||
|
contactPoint.rollingResistanceImpulse = externalContact->getRollingResistanceImpulse();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the split impulses to zero
|
// Initialize the split impulses to zero
|
||||||
|
@ -277,6 +283,13 @@ void ContactSolver::initializeContactConstraints() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the inverse K matrix for the rolling resistance constraint
|
||||||
|
manifold.inverseRollingResistance.setToZero();
|
||||||
|
if (manifold.rollingResistanceFactor > 0 && manifold.isBody1DynamicType || manifold.isBody2DynamicType) {
|
||||||
|
manifold.inverseRollingResistance = manifold.inverseInertiaTensorBody1 + manifold.inverseInertiaTensorBody2;
|
||||||
|
manifold.inverseRollingResistance = manifold.inverseRollingResistance.getInverse();
|
||||||
|
}
|
||||||
|
|
||||||
// If we solve the friction constraints at the center of the contact manifold
|
// If we solve the friction constraints at the center of the contact manifold
|
||||||
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
if (mIsSolveFrictionAtContactManifoldCenterActive) {
|
||||||
|
|
||||||
|
@ -384,6 +397,18 @@ void ContactSolver::warmStart() {
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseFriction2, contactManifold);
|
applyImpulse(impulseFriction2, contactManifold);
|
||||||
|
|
||||||
|
// ------ Rolling resistance------ //
|
||||||
|
|
||||||
|
if (contactManifold.rollingResistanceFactor > 0) {
|
||||||
|
|
||||||
|
// Compute the impulse P = J^T * lambda
|
||||||
|
const Impulse impulseRollingResistance(Vector3::zero(), -contactPoint.rollingResistanceImpulse,
|
||||||
|
Vector3::zero(), contactPoint.rollingResistanceImpulse);
|
||||||
|
|
||||||
|
// Apply the impulses to the bodies of the constraint
|
||||||
|
applyImpulse(impulseRollingResistance, contactManifold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // If it is a new contact point
|
else { // If it is a new contact point
|
||||||
|
@ -392,6 +417,7 @@ void ContactSolver::warmStart() {
|
||||||
contactPoint.penetrationImpulse = 0.0;
|
contactPoint.penetrationImpulse = 0.0;
|
||||||
contactPoint.friction1Impulse = 0.0;
|
contactPoint.friction1Impulse = 0.0;
|
||||||
contactPoint.friction2Impulse = 0.0;
|
contactPoint.friction2Impulse = 0.0;
|
||||||
|
contactPoint.rollingResistanceImpulse = Vector3::zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,6 +482,17 @@ void ContactSolver::warmStart() {
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseTwistFriction, contactManifold);
|
applyImpulse(impulseTwistFriction, contactManifold);
|
||||||
|
|
||||||
|
// ------ Rolling resistance at the center of the contact manifold ------ //
|
||||||
|
|
||||||
|
// Compute the impulse P = J^T * lambda
|
||||||
|
angularImpulseBody1 = -contactManifold.rollingResistanceImpulse;
|
||||||
|
angularImpulseBody2 = contactManifold.rollingResistanceImpulse;
|
||||||
|
const Impulse impulseRollingResistance(Vector3::zero(), angularImpulseBody1,
|
||||||
|
Vector3::zero(), angularImpulseBody2);
|
||||||
|
|
||||||
|
// Apply the impulses to the bodies of the constraint
|
||||||
|
applyImpulse(impulseRollingResistance, contactManifold);
|
||||||
}
|
}
|
||||||
else { // If it is a new contact manifold
|
else { // If it is a new contact manifold
|
||||||
|
|
||||||
|
@ -463,6 +500,7 @@ void ContactSolver::warmStart() {
|
||||||
contactManifold.friction1Impulse = 0.0;
|
contactManifold.friction1Impulse = 0.0;
|
||||||
contactManifold.friction2Impulse = 0.0;
|
contactManifold.friction2Impulse = 0.0;
|
||||||
contactManifold.frictionTwistImpulse = 0.0;
|
contactManifold.frictionTwistImpulse = 0.0;
|
||||||
|
contactManifold.rollingResistanceImpulse = Vector3::zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -604,6 +642,29 @@ void ContactSolver::solve() {
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseFriction2, contactManifold);
|
applyImpulse(impulseFriction2, contactManifold);
|
||||||
|
|
||||||
|
// --------- Rolling resistance constraint --------- //
|
||||||
|
|
||||||
|
if (contactManifold.rollingResistanceFactor > 0) {
|
||||||
|
|
||||||
|
// Compute J*v
|
||||||
|
const Vector3 JvRolling = w2 - w1;
|
||||||
|
|
||||||
|
// Compute the Lagrange multiplier lambda
|
||||||
|
Vector3 deltaLambdaRolling = contactManifold.inverseRollingResistance * (-JvRolling);
|
||||||
|
decimal rollingLimit = contactManifold.rollingResistanceFactor * contactPoint.penetrationImpulse;
|
||||||
|
Vector3 lambdaTempRolling = contactPoint.rollingResistanceImpulse;
|
||||||
|
contactPoint.rollingResistanceImpulse = clamp(contactPoint.rollingResistanceImpulse +
|
||||||
|
deltaLambdaRolling, rollingLimit);
|
||||||
|
deltaLambdaRolling = contactPoint.rollingResistanceImpulse - lambdaTempRolling;
|
||||||
|
|
||||||
|
// Compute the impulse P=J^T * lambda
|
||||||
|
const Impulse impulseRolling(Vector3::zero(), -deltaLambdaRolling,
|
||||||
|
Vector3::zero(), deltaLambdaRolling);
|
||||||
|
|
||||||
|
// Apply the impulses to the bodies of the constraint
|
||||||
|
applyImpulse(impulseRolling, contactManifold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -688,6 +749,31 @@ void ContactSolver::solve() {
|
||||||
|
|
||||||
// Apply the impulses to the bodies of the constraint
|
// Apply the impulses to the bodies of the constraint
|
||||||
applyImpulse(impulseTwistFriction, contactManifold);
|
applyImpulse(impulseTwistFriction, contactManifold);
|
||||||
|
|
||||||
|
// --------- Rolling resistance constraint at the center of the contact manifold --------- //
|
||||||
|
|
||||||
|
if (contactManifold.rollingResistanceFactor > 0) {
|
||||||
|
|
||||||
|
// Compute J*v
|
||||||
|
const Vector3 JvRolling = w2 - w1;
|
||||||
|
|
||||||
|
// Compute the Lagrange multiplier lambda
|
||||||
|
Vector3 deltaLambdaRolling = contactManifold.inverseRollingResistance * (-JvRolling);
|
||||||
|
decimal rollingLimit = contactManifold.rollingResistanceFactor * sumPenetrationImpulse;
|
||||||
|
Vector3 lambdaTempRolling = contactManifold.rollingResistanceImpulse;
|
||||||
|
contactManifold.rollingResistanceImpulse = clamp(contactManifold.rollingResistanceImpulse +
|
||||||
|
deltaLambdaRolling, rollingLimit);
|
||||||
|
deltaLambdaRolling = contactManifold.rollingResistanceImpulse - lambdaTempRolling;
|
||||||
|
|
||||||
|
// Compute the impulse P=J^T * lambda
|
||||||
|
angularImpulseBody1 = -deltaLambdaRolling;
|
||||||
|
angularImpulseBody2 = deltaLambdaRolling;
|
||||||
|
const Impulse impulseRolling(Vector3::zero(), angularImpulseBody1,
|
||||||
|
Vector3::zero(), angularImpulseBody2);
|
||||||
|
|
||||||
|
// Apply the impulses to the bodies of the constraint
|
||||||
|
applyImpulse(impulseRolling, contactManifold);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,6 +794,7 @@ void ContactSolver::storeImpulses() {
|
||||||
contactPoint.externalContact->setPenetrationImpulse(contactPoint.penetrationImpulse);
|
contactPoint.externalContact->setPenetrationImpulse(contactPoint.penetrationImpulse);
|
||||||
contactPoint.externalContact->setFrictionImpulse1(contactPoint.friction1Impulse);
|
contactPoint.externalContact->setFrictionImpulse1(contactPoint.friction1Impulse);
|
||||||
contactPoint.externalContact->setFrictionImpulse2(contactPoint.friction2Impulse);
|
contactPoint.externalContact->setFrictionImpulse2(contactPoint.friction2Impulse);
|
||||||
|
contactPoint.externalContact->setRollingResistanceImpulse(contactPoint.rollingResistanceImpulse);
|
||||||
|
|
||||||
contactPoint.externalContact->setFrictionVector1(contactPoint.frictionVector1);
|
contactPoint.externalContact->setFrictionVector1(contactPoint.frictionVector1);
|
||||||
contactPoint.externalContact->setFrictionVector2(contactPoint.frictionVector2);
|
contactPoint.externalContact->setFrictionVector2(contactPoint.frictionVector2);
|
||||||
|
@ -716,6 +803,7 @@ void ContactSolver::storeImpulses() {
|
||||||
manifold.externalContactManifold->setFrictionImpulse1(manifold.friction1Impulse);
|
manifold.externalContactManifold->setFrictionImpulse1(manifold.friction1Impulse);
|
||||||
manifold.externalContactManifold->setFrictionImpulse2(manifold.friction2Impulse);
|
manifold.externalContactManifold->setFrictionImpulse2(manifold.friction2Impulse);
|
||||||
manifold.externalContactManifold->setFrictionTwistImpulse(manifold.frictionTwistImpulse);
|
manifold.externalContactManifold->setFrictionTwistImpulse(manifold.frictionTwistImpulse);
|
||||||
|
manifold.externalContactManifold->setRollingResistanceImpulse(manifold.rollingResistanceImpulse);
|
||||||
manifold.externalContactManifold->setFrictionVector1(manifold.frictionVector1);
|
manifold.externalContactManifold->setFrictionVector1(manifold.frictionVector1);
|
||||||
manifold.externalContactManifold->setFrictionVector2(manifold.frictionVector2);
|
manifold.externalContactManifold->setFrictionVector2(manifold.frictionVector2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,9 @@ class ContactSolver {
|
||||||
/// Accumulated split impulse for penetration correction
|
/// Accumulated split impulse for penetration correction
|
||||||
decimal penetrationSplitImpulse;
|
decimal penetrationSplitImpulse;
|
||||||
|
|
||||||
|
/// Accumulated rolling resistance impulse
|
||||||
|
Vector3 rollingResistanceImpulse;
|
||||||
|
|
||||||
/// Normal vector of the contact
|
/// Normal vector of the contact
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
|
|
||||||
|
@ -224,12 +227,21 @@ class ContactSolver {
|
||||||
/// Number of contact points
|
/// Number of contact points
|
||||||
uint nbContacts;
|
uint nbContacts;
|
||||||
|
|
||||||
|
/// True if the body 1 is of type dynamic
|
||||||
|
bool isBody1DynamicType;
|
||||||
|
|
||||||
|
/// True if the body 2 is of type dynamic
|
||||||
|
bool isBody2DynamicType;
|
||||||
|
|
||||||
/// Mix of the restitution factor for two bodies
|
/// Mix of the restitution factor for two bodies
|
||||||
decimal restitutionFactor;
|
decimal restitutionFactor;
|
||||||
|
|
||||||
/// Mix friction coefficient for the two bodies
|
/// Mix friction coefficient for the two bodies
|
||||||
decimal frictionCoefficient;
|
decimal frictionCoefficient;
|
||||||
|
|
||||||
|
/// Rolling resistance factor between the two bodies
|
||||||
|
decimal rollingResistanceFactor;
|
||||||
|
|
||||||
/// Pointer to the external contact manifold
|
/// Pointer to the external contact manifold
|
||||||
ContactManifold* externalContactManifold;
|
ContactManifold* externalContactManifold;
|
||||||
|
|
||||||
|
@ -271,6 +283,9 @@ class ContactSolver {
|
||||||
/// Matrix K for the twist friction constraint
|
/// Matrix K for the twist friction constraint
|
||||||
decimal inverseTwistFrictionMass;
|
decimal inverseTwistFrictionMass;
|
||||||
|
|
||||||
|
/// Matrix K for the rolling resistance constraint
|
||||||
|
Matrix3x3 inverseRollingResistance;
|
||||||
|
|
||||||
/// First friction direction at contact manifold center
|
/// First friction direction at contact manifold center
|
||||||
Vector3 frictionVector1;
|
Vector3 frictionVector1;
|
||||||
|
|
||||||
|
@ -291,6 +306,9 @@ class ContactSolver {
|
||||||
|
|
||||||
/// Twist friction impulse at contact manifold center
|
/// Twist friction impulse at contact manifold center
|
||||||
decimal frictionTwistImpulse;
|
decimal frictionTwistImpulse;
|
||||||
|
|
||||||
|
/// Rolling resistance impulse
|
||||||
|
Vector3 rollingResistanceImpulse;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------- Constants --------------------- //
|
// -------------------- Constants --------------------- //
|
||||||
|
@ -360,6 +378,9 @@ class ContactSolver {
|
||||||
decimal computeMixedFrictionCoefficient(RigidBody* body1,
|
decimal computeMixedFrictionCoefficient(RigidBody* body1,
|
||||||
RigidBody* body2) const;
|
RigidBody* body2) const;
|
||||||
|
|
||||||
|
/// Compute th mixed rolling resistance factor between two bodies
|
||||||
|
decimal computeMixedRollingResistance(RigidBody* body1, RigidBody* body2) const;
|
||||||
|
|
||||||
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
/// Compute the two unit orthogonal vectors "t1" and "t2" that span the tangential friction
|
||||||
/// plane for a contact point. The two vectors have to be
|
/// plane for a contact point. The two vectors have to be
|
||||||
/// such that : t1 x t2 = contactNormal.
|
/// such that : t1 x t2 = contactNormal.
|
||||||
|
@ -481,6 +502,12 @@ inline decimal ContactSolver::computeMixedFrictionCoefficient(RigidBody *body1,
|
||||||
body2->getMaterial().getFrictionCoefficient());
|
body2->getMaterial().getFrictionCoefficient());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute th mixed rolling resistance factor between two bodies
|
||||||
|
inline decimal ContactSolver::computeMixedRollingResistance(RigidBody* body1,
|
||||||
|
RigidBody* body2) const {
|
||||||
|
return decimal(0.5f) * (body1->getMaterial().getRollingResistance() + body2->getMaterial().getRollingResistance());
|
||||||
|
}
|
||||||
|
|
||||||
// Compute a penetration constraint impulse
|
// Compute a penetration constraint impulse
|
||||||
inline const Impulse ContactSolver::computePenetrationImpulse(decimal deltaLambda,
|
inline const Impulse ContactSolver::computePenetrationImpulse(decimal deltaLambda,
|
||||||
const ContactPointSolver& contactPoint)
|
const ContactPointSolver& contactPoint)
|
||||||
|
|
|
@ -30,13 +30,16 @@ using namespace reactphysics3d;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
Material::Material()
|
Material::Material()
|
||||||
: mFrictionCoefficient(DEFAULT_FRICTION_COEFFICIENT), mBounciness(DEFAULT_BOUNCINESS) {
|
: mFrictionCoefficient(DEFAULT_FRICTION_COEFFICIENT),
|
||||||
|
mBounciness(DEFAULT_BOUNCINESS),
|
||||||
|
mRollingResistance(DEFAULT_ROLLING_RESISTANCE) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy-constructor
|
// Copy-constructor
|
||||||
Material::Material(const Material& material)
|
Material::Material(const Material& material)
|
||||||
: mFrictionCoefficient(material.mFrictionCoefficient), mBounciness(material.mBounciness) {
|
: mFrictionCoefficient(material.mFrictionCoefficient), mBounciness(material.mBounciness),
|
||||||
|
mRollingResistance(material.mRollingResistance) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ class Material {
|
||||||
/// Friction coefficient (positive value)
|
/// Friction coefficient (positive value)
|
||||||
decimal mFrictionCoefficient;
|
decimal mFrictionCoefficient;
|
||||||
|
|
||||||
|
/// Rolling resistance factor (positive value)
|
||||||
|
decimal mRollingResistance;
|
||||||
|
|
||||||
/// Bounciness during collisions (between 0 and 1) where 1 is for a very bouncy body
|
/// Bounciness during collisions (between 0 and 1) where 1 is for a very bouncy body
|
||||||
decimal mBounciness;
|
decimal mBounciness;
|
||||||
|
|
||||||
|
@ -75,6 +78,12 @@ class Material {
|
||||||
/// Set the friction coefficient.
|
/// Set the friction coefficient.
|
||||||
void setFrictionCoefficient(decimal frictionCoefficient);
|
void setFrictionCoefficient(decimal frictionCoefficient);
|
||||||
|
|
||||||
|
/// Return the rolling resistance factor
|
||||||
|
decimal getRollingResistance() const;
|
||||||
|
|
||||||
|
/// Set the rolling resistance factor
|
||||||
|
void setRollingResistance(decimal rollingResistance);
|
||||||
|
|
||||||
/// Overloaded assignment operator
|
/// Overloaded assignment operator
|
||||||
Material& operator=(const Material& material);
|
Material& operator=(const Material& material);
|
||||||
};
|
};
|
||||||
|
@ -117,6 +126,27 @@ inline void Material::setFrictionCoefficient(decimal frictionCoefficient) {
|
||||||
mFrictionCoefficient = frictionCoefficient;
|
mFrictionCoefficient = frictionCoefficient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the rolling resistance factor. If this value is larger than zero,
|
||||||
|
// it will be used to slow down the body when it is rolling
|
||||||
|
// against another body.
|
||||||
|
/**
|
||||||
|
* @return The rolling resistance factor (positive value)
|
||||||
|
*/
|
||||||
|
inline decimal Material::getRollingResistance() const {
|
||||||
|
return mRollingResistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the rolling resistance factor. If this value is larger than zero,
|
||||||
|
// it will be used to slow down the body when it is rolling
|
||||||
|
// against another body.
|
||||||
|
/**
|
||||||
|
* @param rollingResistance The rolling resistance factor
|
||||||
|
*/
|
||||||
|
inline void Material::setRollingResistance(decimal rollingResistance) {
|
||||||
|
assert(rollingResistance >= 0);
|
||||||
|
mRollingResistance = rollingResistance;
|
||||||
|
}
|
||||||
|
|
||||||
// Overloaded assignment operator
|
// Overloaded assignment operator
|
||||||
inline Material& Material::operator=(const Material& material) {
|
inline Material& Material::operator=(const Material& material) {
|
||||||
|
|
||||||
|
@ -124,6 +154,7 @@ inline Material& Material::operator=(const Material& material) {
|
||||||
if (this != &material) {
|
if (this != &material) {
|
||||||
mFrictionCoefficient = material.mFrictionCoefficient;
|
mFrictionCoefficient = material.mFrictionCoefficient;
|
||||||
mBounciness = material.mBounciness;
|
mBounciness = material.mBounciness;
|
||||||
|
mRollingResistance = material.mRollingResistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return this material
|
// Return this material
|
||||||
|
|
Loading…
Reference in New Issue
Block a user