diff --git a/include/chipmunk/chipmunk_structs.h b/include/chipmunk/chipmunk_structs.h index 1485795d..20c9c001 100644 --- a/include/chipmunk/chipmunk_structs.h +++ b/include/chipmunk/chipmunk_structs.h @@ -239,12 +239,14 @@ typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt); typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef); typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt); typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint); +typedef void (*cpConstraintResetAccImpl)(cpConstraint *constraint); typedef struct cpConstraintClass { cpConstraintPreStepImpl preStep; cpConstraintApplyCachedImpulseImpl applyCachedImpulse; cpConstraintApplyImpulseImpl applyImpulse; cpConstraintGetImpulseImpl getImpulse; + cpConstraintResetAccImpl resetAcc; } cpConstraintClass; struct cpConstraint { diff --git a/src/cpBody.c b/src/cpBody.c index 4ba4b494..d4cd89a6 100644 --- a/src/cpBody.c +++ b/src/cpBody.c @@ -160,6 +160,23 @@ cpBodySetType(cpBody *body, cpBodyType type) body->m_inv = body->i_inv = INFINITY; cpBodyAccumulateMassFromShapes(body); + + // Check any constraints, and if there are + // constraints with another non-DYNAMIC body: + // Reset any accumulated force in constraints attached to the body. + // Reset velocity of the body. These will be NaN or Inf otherwise. + cpConstraint* constraint = body->constraintList; + while (constraint) { + constraint->klass->resetAcc(constraint); + cpBody* a = cpConstraintGetBodyA(constraint); + a->v = cpvzero; + a->w = 0.0f; + cpBody* b = cpConstraintGetBodyB(constraint); + b->v = cpvzero; + b->w = 0.0f; + + constraint = cpConstraintNext(constraint, body); + } } else { body->m = body->i = INFINITY; body->m_inv = body->i_inv = 0.0f; diff --git a/src/cpDampedRotarySpring.c b/src/cpDampedRotarySpring.c index 8d38a545..32f7fb53 100644 --- a/src/cpDampedRotarySpring.c +++ b/src/cpDampedRotarySpring.c @@ -77,11 +77,18 @@ getImpulse(cpDampedRotarySpring *spring) return spring->jAcc; } +static void +resetAcc(cpDampedRotarySpring *spring) +{ + spring->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpDampedRotarySpring * diff --git a/src/cpDampedSpring.c b/src/cpDampedSpring.c index e4d019e9..c057abed 100644 --- a/src/cpDampedSpring.c +++ b/src/cpDampedSpring.c @@ -82,11 +82,18 @@ getImpulse(cpDampedSpring *spring) return spring->jAcc; } +static void +resetAcc(cpDampedSpring *spring) +{ + spring->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpDampedSpring * diff --git a/src/cpGearJoint.c b/src/cpGearJoint.c index 3670173b..57e91282 100644 --- a/src/cpGearJoint.c +++ b/src/cpGearJoint.c @@ -74,11 +74,18 @@ getImpulse(cpGearJoint *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpGearJoint *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpGearJoint * diff --git a/src/cpGrooveJoint.c b/src/cpGrooveJoint.c index 50d1857d..56cecf2e 100644 --- a/src/cpGrooveJoint.c +++ b/src/cpGrooveJoint.c @@ -103,11 +103,18 @@ getImpulse(cpGrooveJoint *joint) return cpvlength(joint->jAcc); } +static void +resetAcc(cpGrooveJoint *joint) +{ + joint->jAcc = cpvzero; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpGrooveJoint * diff --git a/src/cpPinJoint.c b/src/cpPinJoint.c index 545e78bf..d4f7b111 100644 --- a/src/cpPinJoint.c +++ b/src/cpPinJoint.c @@ -80,14 +80,20 @@ getImpulse(cpPinJoint *joint) return cpfabs(joint->jnAcc); } +static void +resetAcc(cpPinJoint *joint) +{ + joint->jnAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; - cpPinJoint * cpPinJointAlloc(void) { diff --git a/src/cpPivotJoint.c b/src/cpPivotJoint.c index e45ba072..44f215df 100644 --- a/src/cpPivotJoint.c +++ b/src/cpPivotJoint.c @@ -70,9 +70,15 @@ applyImpulse(cpPivotJoint *joint, cpFloat dt) } static cpFloat -getImpulse(cpConstraint *joint) +getImpulse(cpPivotJoint *joint) { - return cpvlength(((cpPivotJoint *)joint)->jAcc); + return cpvlength(joint->jAcc); +} + +static void +resetAcc(cpPivotJoint *joint) +{ + joint->jAcc = cpvzero; } static const cpConstraintClass klass = { @@ -80,6 +86,7 @@ static const cpConstraintClass klass = { (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpPivotJoint * diff --git a/src/cpRatchetJoint.c b/src/cpRatchetJoint.c index b3c9687e..0344f4f6 100644 --- a/src/cpRatchetJoint.c +++ b/src/cpRatchetJoint.c @@ -94,11 +94,18 @@ getImpulse(cpRatchetJoint *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpRatchetJoint *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpRatchetJoint * diff --git a/src/cpRotaryLimitJoint.c b/src/cpRotaryLimitJoint.c index 548adbeb..2710b827 100644 --- a/src/cpRotaryLimitJoint.c +++ b/src/cpRotaryLimitJoint.c @@ -91,11 +91,18 @@ getImpulse(cpRotaryLimitJoint *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpRotaryLimitJoint *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpRotaryLimitJoint * diff --git a/src/cpSimpleMotor.c b/src/cpSimpleMotor.c index 2bea74a5..cda6a602 100644 --- a/src/cpSimpleMotor.c +++ b/src/cpSimpleMotor.c @@ -70,11 +70,18 @@ getImpulse(cpSimpleMotor *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpSimpleMotor *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpSimpleMotor * diff --git a/src/cpSlideJoint.c b/src/cpSlideJoint.c index 61afe33e..7279867a 100644 --- a/src/cpSlideJoint.c +++ b/src/cpSlideJoint.c @@ -89,9 +89,15 @@ applyImpulse(cpSlideJoint *joint, cpFloat dt) } static cpFloat -getImpulse(cpConstraint *joint) +getImpulse(cpSlideJoint *joint) { - return cpfabs(((cpSlideJoint *)joint)->jnAcc); + return cpfabs(joint->jnAcc); +} + +static void +resetAcc(cpSlideJoint *joint) +{ + joint->jnAcc = 0.0f; } static const cpConstraintClass klass = {