contact.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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
  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) SetNormal(newNormal *math32.Vector3) {
  28. ce.nA = newNormal
  29. }
  30. func (ce *Contact) Normal() math32.Vector3 {
  31. return *ce.nA
  32. }
  33. func (ce *Contact) SetRA(newRi *math32.Vector3) {
  34. ce.rA = newRi
  35. }
  36. func (ce *Contact) RA() math32.Vector3 {
  37. return *ce.rA
  38. }
  39. func (ce *Contact) SetRB(newRj *math32.Vector3) {
  40. ce.rB = newRj
  41. }
  42. func (ce *Contact) RB() math32.Vector3 {
  43. return *ce.rB
  44. }
  45. // ComputeB
  46. func (ce *Contact) ComputeB(h float32) float32 {
  47. vA := ce.bA.Velocity()
  48. wA := ce.bA.AngularVelocity()
  49. vB := ce.bB.Velocity()
  50. wB := ce.bB.AngularVelocity()
  51. // Calculate cross products
  52. rnA := math32.NewVec3().CrossVectors(ce.rA, ce.nA)
  53. rnB := math32.NewVec3().CrossVectors(ce.rB, ce.nA)
  54. // g = xj+rB -(xi+rA)
  55. // G = [ -nA -rnA nA rnB ]
  56. ce.jeA.SetSpatial(ce.nA.Clone().Negate())
  57. ce.jeA.SetRotational(rnA.Clone().Negate())
  58. ce.jeB.SetSpatial(ce.nA.Clone())
  59. ce.jeB.SetRotational(rnB.Clone())
  60. // Calculate the penetration vector
  61. posA := ce.bA.Position()
  62. posB := ce.bB.Position()
  63. (&posB).Add(ce.rB)
  64. x := (&posA).Sub(&posB)
  65. penetrationVec := ce.rA.Clone().Sub(x)
  66. g := ce.nA.Dot(penetrationVec)
  67. // Compute iteration
  68. ePlusOne := ce.restitution + 1
  69. GW := ePlusOne * vB.Dot(ce.nA) - ePlusOne * vA.Dot(ce.nA) + wB.Dot(rnB) - wA.Dot(rnA)
  70. GiMf := ce.ComputeGiMf()
  71. return -g*ce.a - GW*ce.b - h*GiMf
  72. }
  73. //// GetImpactVelocityAlongNormal returns the current relative velocity at the contact point.
  74. //func (ce *Contact) GetImpactVelocityAlongNormal() float32 {
  75. //
  76. // xi := ce.bA.Position().Add(ce.rA)
  77. // xj := ce.bB.Position().Add(ce.rB)
  78. //
  79. // vi := ce.bA.GetVelocityAtWorldPoint(xi)
  80. // vj := ce.bB.GetVelocityAtWorldPoint(xj)
  81. //
  82. // relVel := math32.NewVec3().SubVectors(vi, vj)
  83. //
  84. // return ce.nA.Dot(relVel)
  85. //}