Concepts for Programming a Rigid Body Physics Engine
Concepts for Programming a Rigid Body Physics Engine Part 2 Presented by Scott Hawkins
source: Game Physics Engine Development by Ian Millington
Topics • Collision Resolution – Resolving Velocities – Resolving Positions • Friction
Collision Resolution • We have been given a list of contacts, each containing: – – – references to the two rigid bodies contact point in world coordinates, q contact normal in world coordinates, n penetration depth, d coefficient of restituion, c coefficient of friction, μ (Vector) (real)
Collision Resolution • After we detect collisions, what needs to be updated? – positions – orientations – velocities – angular velocities
Collision Resolution • Two steps – Resolve velocities (and angular velocities) – Resolve positions (and orientations)
Collision Resolution • Resolving velocities – Find the closing velocity for each contact – Choose the contact with greatest closing velocity – Resolve velocities for this contact (do not remove it from the list of contacts) – Repeat this until either • (1) all contacts are resolved, or • (2) we run out of iterations
Finding Closing Velocity • “Closing velocity” is the speed at which the two objects are moving toward each other at the point of contact. • We need this information to determine which contact to resolve first.
Finding Closing Velocity • How to find the closing velocity? – Find the velocity at the contact point for each object – Take the component in the direction of the contact – Sum them together
Finding Closing Velocity • How do you find the velocity of a point on a spinning object? – Start with the object’s overall velocity and add the component due to rotation • vpoint = p’ + θ’ x (ppoint - p) – where ppoint is the position of the point in world coordinates
Finding Closing Velocities • For a rigid body collision, some component of the closing velocity may result from rotation vs
Finding Closing Velocity • We want the velocity of each object at the contact point – We were given q, the contact point in world coordinates • vcontact, a = p’a + θ’a x (q - pa) • vcontact, b = p’b + θ’b x (q - pb)
Finding Closing Velocity • Find the component of this in the direction of the contact – We were given n, the contact normal, which is a unit vector pointing from object a to object b • vc, a = vcontact, a · n • vc, b = vcontact, b · -n – Use -n in the second equation because we want the component going from object b to object a
Finding Closing Velocity • Sum the components from each object to get the total closing velocity, vc • vc = vc, a + vc, b
Choosing the Greatest Closing Velocity • We now have the closing velocity for each contact • Choosing the greatest closing velocity will take O(n) time normally – use a max-heap?
Resolving Velocities • How to update velocity and angular velocity for a pair of colliding objects? • Accomplish this by applying some impulse, g (which we will find) • g represents a change in momentum • g = Δ(mv)
Resolving Velocities • This also creates an impulsive torque, u, given by: • u = (q - p) x g – Once again, q is the contact point in world coordinates
Resolving Velocities • To apply g to the objects: • Δp’a = ma-1 g • Δθ’a = Ia-1 ua = Ia-1[(q - pa) x g] • Δp’b = mb-1(-g) • Δθ’b = Ib-1 ub = Ib-1[(q - pb) x (-g)] – Be sure to use -g for object b – I-1 in these equations is in world coordinates
Resolving Velocities • How to choose g?
Resolving Velocities • We want the objects to bounce off of each other according to the coefficient of restitution, c • vc, after = -cvc • At the contact point, and in the direction of the contact normal, we want a velocity change of Δv • Δv = -cvc - vc = -(1 + c)vc
Resolving Velocities • How can we choose g to generate this result? – We already know the direction of g • It must point in the direction of the contact normal, since it is like a normal force acting over an infinitely short time interval – Find the magnitude g by expressing g as • g = gn and plugging it into the previous equations
Resolving Velocities • If we applied the impulse gn, we would get: • Δp’a = ma-1 gn • Δθ’a = Ia-1[(q - pa) x gn] • Δp’b = -mb-1 gn • Δθ’b = -Ib-1[(q - pb) x gn]
Resolving Velocities • This causes a change in velocity at the contact point: • Δvcontact, a = Δp’a + Δθ’a x (q - pa) = ma-1 gn + (Ia-1[(q - pa) x gn]) x (q - pa) = g[ma-1 n + (Ia-1[(q - pa) x n]) x (q - pa)] • Δvcontact, b = Δp’b + Δθ’b x (q - pb) = -mb-1 gn + (-Ib-1[(q - pb) x gn]) x (q - pb) = -g[mb-1 n + (Ib-1[(q - pb) x n]) x (q - pb)]
Resolving Velocities • This contributes to a change in closing velocity: • Δvc, a = Δvcontact, a · n = g[ma-1 n + (Ia-1[(q - pa) x n]) x (q - pa)] · n = g(ma-1 + [(Ia-1[(q - pa) x n]) x (q - pa)] · n) • Δvc, b = Δvcontact, b · -n = -g[mb-1 n + (Ib-1[(q - pb) x n]) x (q - pb)] · -n = g(mb-1 + [(Ib-1[(q - pb) x n]) x (q - pb)] · n)
Resolving Velocities • Add these to get the total change in closing velocity: • Δvc = Δvc, a + Δvc, b = g(ma-1 + [(Ia-1[(q - pa) x n]) x (q - pa)] · n) + g(mb-1 + [(Ib-1[(q - pb) x n]) x (q - pb)] · n) = -(1 + c)vc
Resolving Velocities • Now we can isolate g • g = -(1 + c)vc / (ma-1 + [(Ia-1[(q - pa) x n]) x (q - pa)] · n + mb-1 + [(Ib-1[(q - pb) x n]) x (q - pb)] · n) • g = gn • Apply g to the objects as we discussed earlier
Resolving Velocities • After resolving the velocities for one contact, update its closing velocity to be • vc, after = -cvc – Update the closing velocities for every contact involving one of the two bodies that were changed This contact was resolved These need to update vc
Resolving Velocities • Continue resolving whichever contact has the greatest closing velocity until either – (1) all contacts are resolved (all closing velocities are less than or equal to zero) or – (2) we run out of iterations
Collision Resolution • Resolving positions – Choose the contact with greatest interpenetration depth – Resolve positions for this contact (do not remove it from the list of contacts) – Repeat this until either • (1) all contacts are resolved, or • (2) we run out of iterations
Choosing the Greatest Interpenetration Depth • The interpenetration depth d at each contact is given to us by the collision detector • Use another max-heap?
Resolving Positions • How to update position and orientation for a pair of colliding objects? – We apply changes in position and orientation to each object to make d = 0 – The changes we need to find are • Δpa, Δθa, Δpb, and Δθb
Resolving Positions • Once we have Δpa, Δθa, Δpb, and Δθb, we can perform the update • pa, after = pa + Δpa • θa, after = θa + ½(Δθa)(θa) – where Δθa = 0 + Δθa, x i + Δθa, y j + Δθa, z k and Δθa, x, Δθa, y, Δθa, z are components of Δθa • pb, after = pb + Δpb • θb, after = θb + ½(Δθb)(θb) – where Δθb = 0 + Δθb, x i + Δθb, y j + Δθb, z k and Δθb, x, Δθb, y, Δθb, z are components of Δθb
Resolving Positions • How do we decide what those changes should be?
Resolving Positions • Millington uses an approximation – Treat distance moved around a circle as if it were in a straight line
Resolving Positions • Interpenetration depth d resolved through a combination of linear and rotational movement from both objects • d = linear movement of a + angular movement of a + linear movement of b + angular movement of b
Resolving Positions • Each movement contributes some fraction of the total distance • linear movement of a = w 1 d • angular movement of a = w 2 d • linear movement of b = w 3 d • angular movement of b = w 4 d – where w 1, w 2, w 3, and w 4 are weights between 0 and 1 such that • w 1 + w 2 + w 3 + w 4 = 1
Resolving Positions • Impulse – To resolve velocities, the “impulse” we want is a force integrated over a short time • units are kg·m/s – To resolve positions, we need an “impulse” that is force integrated twice over a short time • units are kg·m
Resolving Positions • Inertia – normally, an object’s tendency to resist a change in motion – in this case, we say “inertia” is an object’s response to one kg·m of “impulse”
Resolving Positions • Choose w 1, w 2, w 3, and w 4 based on inertia • w 1 = linear inertia of a / total inertia • w 2 = angular inertia of a / total inertia • w 3 = linear inertia of b / total inertia • w 4 = angular inertia of b / total inertia • total inertia = linear inertia of a + angular inertia of a + linear inertia of b + angular inertia of b
Resolving Positions • Linear Inertia – How much linear movement occurs in response to a unit impulse? – (different kind of impulse than before) • linear inertia of a = m-1 a • linear inertia of b = m-1 b
Resolving Positions • Angular Inertia – How much angular movement occurs in response to a unit impulse? (in the direction of the contact) • angular inertia of a = [(I-1 a[(q - pa) x n]) x (q - pa)] · n • angular inertia of b = [(I-1 b[(q - pb) x n]) x (q - pb)] · n
Resolving Positions • We can now find the weights w 1, w 2, w 3, and w 4 • w 1 = m-1 a / total inertia • w 2 = [(I-1 a[(q - pa) x n]) x (q - pa)] · n / total inertia • w 3 = m-1 b / total inertia • w 4 = [(I-1 b[(q - pb) x n]) x (q - pb)] · n / total inertia • total inertia = m-1 a + [(I-1 a[(q - pa) x n]) x (q - pa)] · n + m-1 b + [(I-1 b[(q - pb) x n]) x (q - pb)] · n
Resolving Positions • Using these weights, we can find how much of each type of movement should occur • linear movement of a = w 1 d • angular movement of a = w 2 d • linear movement of b = w 3 d • angular movement of b = w 4 d
Resolving Positions • How can we generate this much movement?
Resolving Positions • Linear movement • Δpa = -n * linear movement of a • Δpb = n * linear movement of b
Resolving Positions • Angular Movement • How much rotation? – We are given an amount of movement – Find ratio of impulse per movement – Find ratio of rotation per impulse – rotation = (movement) * (impulse / movement) * (rotation / impulse)
Resolving Positions • How to find ratio of impulse per movement? – The angular inertia we used before was a ratio of movement per impulse • (impulse/movement)a = (angular inertia of a)-1 • (impulse/movement)b = (angular inertia of b)-1
Resolving Positions • How to find ratio of rotation per impulse? • (rotation/impulse)a = I-1 a((q - pa) x n) • (rotation/impulse)b = I-1 b((q - pb) x (-n)) – Use -n for object b, since it must receive an impulse in the opposite direction
Resolving Positions • Putting it all together • Δθa = rotationa = (movement)a * (impulse / movement)a * (rotation / impulse)a = w 2 d * (angular inertia of a)-1 * I-1 a((q - pa) x n) = (angular inertia of a / total inertia) * d * (angular inertia of a)-1 * I-1 a((q - pa) x n)
Resolving Positions • Putting it all together • Δθb = rotationb = (movement)b * (impulse / movement)b * (rotation / impulse)b = w 4 d * (angular inertia of b)-1 * I-1 b((q - pb) x (-n)) = (angular inertia of b / total inertia) * d * (angular inertia of b)-1 * I-1 b((q - pb) x (-n))
Resolving Positions • Apply Δpa, Δθa, Δpb, and Δθb to the objects as we discussed earlier
Resolving Positions • After resolving the positions for one contact, update the penetration depth for related contacts This contact was resolved These need to update d
Resolving Positions • To update the penetration depth d for a related contact • Δd = (Δp + (Δθ x (q - p))) · n
Resolving Positions • Continue resolving whichever contact has the greatest penetration depth until either – (1) all contacts are resolved (all penetration depths are less than or equal to zero) or – (2) we run out of iterations
Friction • We want a frictional impulse gf • ||gf|| <= μ||g|| • gf is in the direction that will eliminate perpendicular components of the objects’s relative motion
Friction • To find the direction of gf – Find the components of the objects’ velocities perpendicular to the contact • vperp, a = vcontact, a - vcontact, a(vcontact, a · n)/||vcontact, a|| • vperp, b = vcontact, b - vcontact, b(vcontact, b · -n)/|| vcontact, b|| • vperp, total = vperp, a - vperp, b • gf = -||gf||vperp, total
Friction • To find the magnitude of gf – Find the greatest possible value for ||gf|| that satisfies the inequalities • ||gf|| <= μ||g|| • ||Δvperp, total|| <= ||vperp, total||
- Slides: 57