Expose total normal impulses, improve contact impulse APIs#788
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
ContactPointstores anormal_impulse. However, this is the clamped accumulated normal impulse from the last substep, used for warm starting the solver. It does not represent the total impulse applied across substeps and restitution, despite the ambiguous name.As such, we are currently missing a proper way for users to determine how "strong" a contact is. Exposing this is important for numerous gameplay scenarios, like determining when a glass bottle or window should shatter, or how much damage a hit should deal.
Solution
Rename the current
ContactPointpropertiesnormal_impulseandtangent_impulsetowarm_start_normal_impulseandwarm_start_tangent_impulse, and expose a newnormal_impulsethat represents the total normal impulse applied across substeps and restitution.Contact constraints still store a
normal_impulsewith the old semantics, but themax_normal_impulsehas been renamed tototal_normal_impulse, which contains the total normal impulse. Some of the solver code here has also been slightly modified to fix some problems and work with the new semantics.The method APIs like
ContactPair::total_normal_impulsehave been updated accordingly.ContactPair::max_normal_impulsehas also been split intoContactPair::max_normal_impulse(returns a vector) andContactPair::max_normal_impulse_magnitude(returns a scalar).Comparison to Box2D
Box2D has the same property, but there the warm starting impulse is stored on
b2ManifoldPointasnormalImpulse, and the total normal impulse is stored astotalNormalImpulse. The former is intended to be more internal, and the latter is intended for gameplay purposes.Using the more obvious name
normalImpulsefor the value intended for internals seems like an odd API choice to me, so I instead opted to makenormal_impulsewhat users would expect to use, and give the less obvious / longer name to the warm starting impulse aswarm_start_normal_impulse.Migration Guide
ContactPoint::normal_impulsepreviously corresponded to the clamped accumulated normal impulse from the last substep, used for warm starting the contact solver. It did not represent the total impulse applied across substeps and restitution, despite the ambiguous name.Now,
ContactPoint::normal_impulseworks like you would expect, and represents the total normal impulse applied at a contact point. Divide by the time step to get the corresponding force.The old warm starting impulses are now stored as
warm_start_normal_impulseandwarm_start_tangent_impulse(previouslytangent_impulse).The method APIs such as
total_normal_impulse,total_normal_impulse_magnitude, andmax_normal_impulsehave been updated accordingly to use the newnormal_impulse. Additionally,ContactPair::max_normal_impulsehas been split intoContactPair::max_normal_impulse(returns a vector) andContactPair::max_normal_impulse_magnitude(returns a scalar).The
normal_forceandtangent_forcemethods ofContactPointhave been removed.ContactConstraintPoint::max_normal_impulseis now stored in theContactNormalPartastotal_impulse.