contact.go 2.8 KB

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