contact.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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. // Contact is a contact/non-penetration constraint equation.
  9. type Contact struct {
  10. Equation
  11. restitution float32 // "bounciness": u1 = -e*u0
  12. rA *math32.Vector3 // World-oriented vector that goes from the center of bA to the contact point.
  13. rB *math32.Vector3 // World-oriented vector that goes from the center of bB to the contact point.
  14. nA *math32.Vector3 // Contact normal, pointing out of body A.
  15. }
  16. // NewContact creates and returns a pointer to a new Contact equation object.
  17. func NewContact(bodyA, bodyB IBody, minForce, maxForce float32) *Contact {
  18. ce := new(Contact)
  19. // minForce default should be 0.
  20. ce.restitution = 0.5
  21. ce.rA = &math32.Vector3{0, 0, 0}
  22. ce.rB = &math32.Vector3{0, 0, 0}
  23. ce.nA = &math32.Vector3{0, 0, 0}
  24. ce.Equation.initialize(bodyA, bodyB, minForce, maxForce)
  25. return ce
  26. }
  27. func (ce *Contact) SetRestitution(r float32) {
  28. ce.restitution = r
  29. }
  30. func (ce *Contact) Restitution() float32 {
  31. return ce.restitution
  32. }
  33. func (ce *Contact) SetNormal(newNormal *math32.Vector3) {
  34. ce.nA = newNormal
  35. }
  36. func (ce *Contact) Normal() math32.Vector3 {
  37. return *ce.nA
  38. }
  39. func (ce *Contact) SetRA(newRa *math32.Vector3) {
  40. ce.rA = newRa
  41. }
  42. func (ce *Contact) RA() math32.Vector3 {
  43. return *ce.rA
  44. }
  45. func (ce *Contact) SetRB(newRb *math32.Vector3) {
  46. ce.rB = newRb
  47. }
  48. func (ce *Contact) RB() math32.Vector3 {
  49. return *ce.rB
  50. }
  51. // ComputeB
  52. func (ce *Contact) ComputeB(h float32) float32 {
  53. vA := ce.bA.Velocity()
  54. wA := ce.bA.AngularVelocity()
  55. vB := ce.bB.Velocity()
  56. wB := ce.bB.AngularVelocity()
  57. // Calculate cross products
  58. rnA := math32.NewVec3().CrossVectors(ce.rA, ce.nA)
  59. rnB := math32.NewVec3().CrossVectors(ce.rB, ce.nA)
  60. // g = xj+rB -(xi+rA)
  61. // G = [ -nA -rnA nA rnB ]
  62. ce.jeA.SetSpatial(ce.nA.Clone().Negate())
  63. ce.jeA.SetRotational(rnA.Clone().Negate())
  64. ce.jeB.SetSpatial(ce.nA.Clone())
  65. ce.jeB.SetRotational(rnB.Clone())
  66. // Calculate the penetration vector
  67. posA := ce.bA.Position()
  68. posB := ce.bB.Position()
  69. penetrationVec := ce.rB.Clone().Add(&posB).Sub(ce.rA).Sub(&posA)
  70. g := ce.nA.Dot(penetrationVec)
  71. // Compute iteration
  72. ePlusOne := ce.restitution + 1
  73. GW := ePlusOne*vB.Dot(ce.nA) - ePlusOne*vA.Dot(ce.nA) + wB.Dot(rnB) - wA.Dot(rnA)
  74. GiMf := ce.ComputeGiMf()
  75. return -g*ce.a - GW*ce.b - h*GiMf
  76. }
  77. //// GetImpactVelocityAlongNormal returns the current relative velocity at the contact point.
  78. //func (ce *Contact) GetImpactVelocityAlongNormal() float32 {
  79. //
  80. // xi := ce.bA.Position().Add(ce.rA)
  81. // xj := ce.bB.Position().Add(ce.rB)
  82. //
  83. // vi := ce.bA.GetVelocityAtWorldPoint(xi)
  84. // vj := ce.bB.GetVelocityAtWorldPoint(xj)
  85. //
  86. // relVel := math32.NewVec3().SubVectors(vi, vj)
  87. //
  88. // return ce.nA.Dot(relVel)
  89. //}