(data B2SolverData)
| 280 | } |
| 281 | |
| 282 | func (joint *B2DistanceJoint) SolvePositionConstraints(data B2SolverData) bool { |
| 283 | if joint.M_frequencyHz > 0.0 { |
| 284 | // There is no position correction for soft distance constraints. |
| 285 | return true |
| 286 | } |
| 287 | |
| 288 | cA := data.Positions[joint.M_indexA].C |
| 289 | aA := data.Positions[joint.M_indexA].A |
| 290 | cB := data.Positions[joint.M_indexB].C |
| 291 | aB := data.Positions[joint.M_indexB].A |
| 292 | |
| 293 | qA := MakeB2RotFromAngle(aA) |
| 294 | qB := MakeB2RotFromAngle(aB) |
| 295 | |
| 296 | rA := B2RotVec2Mul(qA, B2Vec2Sub(joint.M_localAnchorA, joint.M_localCenterA)) |
| 297 | rB := B2RotVec2Mul(qB, B2Vec2Sub(joint.M_localAnchorB, joint.M_localCenterB)) |
| 298 | u := B2Vec2Sub(B2Vec2Sub(B2Vec2Add(cB, rB), cA), rA) |
| 299 | |
| 300 | length := u.Normalize() |
| 301 | C := length - joint.M_length |
| 302 | C = B2FloatClamp(C, -B2_maxLinearCorrection, B2_maxLinearCorrection) |
| 303 | |
| 304 | impulse := -joint.M_mass * C |
| 305 | P := B2Vec2MulScalar(impulse, u) |
| 306 | |
| 307 | cA.OperatorMinusInplace(B2Vec2MulScalar(joint.M_invMassA, P)) |
| 308 | aA -= joint.M_invIA * B2Vec2Cross(rA, P) |
| 309 | cB.OperatorPlusInplace(B2Vec2MulScalar(joint.M_invMassB, P)) |
| 310 | aB += joint.M_invIB * B2Vec2Cross(rB, P) |
| 311 | |
| 312 | // Note: mutation on value, not ref; but OK because Positions is an array |
| 313 | data.Positions[joint.M_indexA].C = cA |
| 314 | data.Positions[joint.M_indexA].A = aA |
| 315 | data.Positions[joint.M_indexB].C = cB |
| 316 | data.Positions[joint.M_indexB].A = aB |
| 317 | |
| 318 | return math.Abs(C) < B2_linearSlop |
| 319 | } |
| 320 | |
| 321 | func (joint B2DistanceJoint) GetAnchorA() B2Vec2 { |
| 322 | return joint.M_bodyA.GetWorldPoint(joint.M_localAnchorA) |
nothing calls this directly
no test coverage detected