rotational.go 2.0 KB

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