friction.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package equation
  5. import (
  6. "github.com/g3n/engine/math32"
  7. )
  8. // Friction is a friction constraint equation.
  9. type Friction struct {
  10. Equation
  11. rA *math32.Vector3 // World-oriented vector that goes from the center of bA to the contact point.
  12. rB *math32.Vector3 // World-oriented vector that starts in body j position and goes to the contact point.
  13. t *math32.Vector3 // Contact tangent
  14. }
  15. // NewFriction creates and returns a pointer to a new Friction equation object.
  16. // slipForce should be +-F_friction = +-mu * F_normal = +-mu * m * g
  17. func NewFriction(bodyA, bodyB IBody, slipForce float32) *Friction {
  18. fe := new(Friction)
  19. fe.rA = math32.NewVec3()
  20. fe.rB = math32.NewVec3()
  21. fe.t = math32.NewVec3()
  22. fe.Equation.initialize(bodyA, bodyB, -slipForce, slipForce)
  23. return fe
  24. }
  25. func (fe *Friction) SetTangent(newTangent *math32.Vector3) {
  26. fe.t = newTangent
  27. }
  28. func (fe *Friction) Tangent() math32.Vector3 {
  29. return *fe.t
  30. }
  31. func (fe *Friction) SetRA(newRa *math32.Vector3) {
  32. fe.rA = newRa
  33. }
  34. func (fe *Friction) RA() math32.Vector3 {
  35. return *fe.rA
  36. }
  37. func (fe *Friction) SetRB(newRb *math32.Vector3) {
  38. fe.rB = newRb
  39. }
  40. func (fe *Friction) RB() math32.Vector3 {
  41. return *fe.rB
  42. }
  43. // ComputeB
  44. func (fe *Friction) ComputeB(h float32) float32 {
  45. // Calculate cross products
  46. rtA := math32.NewVec3().CrossVectors(fe.rA, fe.t)
  47. rtB := math32.NewVec3().CrossVectors(fe.rB, fe.t)
  48. // G = [-t -rtA t rtB]
  49. // And remember, this is a pure velocity constraint, g is always zero!
  50. fe.jeA.SetSpatial(fe.t.Clone().Negate())
  51. fe.jeA.SetRotational(rtA.Clone().Negate())
  52. fe.jeB.SetSpatial(fe.t.Clone())
  53. fe.jeB.SetRotational(rtB.Clone())
  54. var GW = fe.ComputeGW()
  55. var GiMf = fe.ComputeGiMf()
  56. return -GW*fe.b - h*GiMf
  57. }