rotational.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. // Rotational is a rotational constraint equation.
  10. // Works to keep the local vectors orthogonal to each other in world space.
  11. type Rotational struct {
  12. Equation
  13. axisA *math32.Vector3 // Local axis in A
  14. axisB *math32.Vector3 // Local axis in B
  15. maxAngle float32 // Max angle
  16. }
  17. // NewRotational creates and returns a pointer to a new Rotational equation object.
  18. func NewRotational(bodyA, bodyB IBody, maxForce float32) *Rotational {
  19. re := new(Rotational)
  20. re.axisA = math32.NewVector3(1, 0, 0)
  21. re.axisB = math32.NewVector3(0, 1, 0)
  22. re.maxAngle = math32.Pi / 2
  23. re.Equation.initialize(bodyA, bodyB, -maxForce, maxForce)
  24. return re
  25. }
  26. // SetAxisA sets the axis of body A.
  27. func (re *Rotational) SetAxisA(axisA *math32.Vector3) {
  28. re.axisA = axisA
  29. }
  30. // AxisA returns the axis of body A.
  31. func (re *Rotational) AxisA() math32.Vector3 {
  32. return *re.axisA
  33. }
  34. // SetAxisB sets the axis of body B.
  35. func (re *Rotational) SetAxisB(axisB *math32.Vector3) {
  36. re.axisB = axisB
  37. }
  38. // AxisB returns the axis of body B.
  39. func (re *Rotational) AxisB() math32.Vector3 {
  40. return *re.axisB
  41. }
  42. // SetAngle sets the maximum angle.
  43. func (re *Rotational) SetMaxAngle(angle float32) {
  44. re.maxAngle = angle
  45. }
  46. // MaxAngle returns the maximum angle.
  47. func (re *Rotational) MaxAngle() float32 {
  48. return re.maxAngle
  49. }
  50. // ComputeB
  51. func (re *Rotational) ComputeB(h float32) float32 {
  52. // Calculate cross products
  53. nAnB := math32.NewVec3().CrossVectors(re.axisA, re.axisB)
  54. nBnA := math32.NewVec3().CrossVectors(re.axisB, re.axisA)
  55. // g = nA * nj
  56. // gdot = (nj x nA) * wi + (nA x nj) * wj
  57. // G = [0 nBnA 0 nAnB]
  58. // W = [vi wi vj wj]
  59. re.jeA.SetRotational(nBnA)
  60. re.jeB.SetRotational(nAnB)
  61. g := math32.Cos(re.maxAngle) - re.axisA.Dot(re.axisB)
  62. GW := re.ComputeGW()
  63. GiMf := re.ComputeGiMf()
  64. return -g*re.a - GW*re.b - h*GiMf
  65. }