hinge.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 constraint
  5. import (
  6. "github.com/g3n/engine/experimental/physics/equation"
  7. "github.com/g3n/engine/math32"
  8. )
  9. // Hinge constraint.
  10. // Think of it as a door hinge.
  11. // It tries to keep the door in the correct place and with the correct orientation.
  12. type Hinge struct {
  13. PointToPoint
  14. axisA *math32.Vector3 // Rotation axis, defined locally in bodyA.
  15. axisB *math32.Vector3 // Rotation axis, defined locally in bodyB.
  16. rotEq1 *equation.Rotational
  17. rotEq2 *equation.Rotational
  18. motorEq *equation.RotationalMotor
  19. }
  20. // NewHinge creates and returns a pointer to a new Hinge constraint object.
  21. func NewHinge(bodyA, bodyB IBody, pivotA, pivotB, axisA, axisB *math32.Vector3, maxForce float32) *Hinge {
  22. hc := new(Hinge)
  23. hc.initialize(bodyA, bodyB, pivotA, pivotB, maxForce)
  24. hc.axisA = axisA
  25. hc.axisB = axisB
  26. hc.axisA.Normalize()
  27. hc.axisB.Normalize()
  28. hc.rotEq1 = equation.NewRotational(bodyA, bodyB, maxForce)
  29. hc.rotEq2 = equation.NewRotational(bodyA, bodyB, maxForce)
  30. hc.motorEq = equation.NewRotationalMotor(bodyA, bodyB, maxForce)
  31. hc.motorEq.SetEnabled(false) // Not enabled by default
  32. hc.AddEquation(hc.rotEq1)
  33. hc.AddEquation(hc.rotEq2)
  34. hc.AddEquation(hc.motorEq)
  35. return hc
  36. }
  37. func (hc *Hinge) SetMotorEnabled(state bool) {
  38. hc.motorEq.SetEnabled(state)
  39. }
  40. func (hc *Hinge) SetMotorSpeed(speed float32) {
  41. hc.motorEq.SetTargetSpeed(speed)
  42. }
  43. func (hc *Hinge) SetMotorMaxForce(maxForce float32) {
  44. hc.motorEq.SetMaxForce(maxForce)
  45. hc.motorEq.SetMinForce(-maxForce)
  46. }
  47. // Update updates the equations with data.
  48. func (hc *Hinge) Update() {
  49. hc.PointToPoint.Update()
  50. // Get world axes
  51. quatA := hc.bodyA.Quaternion()
  52. quatB := hc.bodyB.Quaternion()
  53. worldAxisA := hc.axisA.Clone().ApplyQuaternion(quatA)
  54. worldAxisB := hc.axisB.Clone().ApplyQuaternion(quatB)
  55. t1, t2 := worldAxisA.RandomTangents()
  56. hc.rotEq1.SetAxisA(t1)
  57. hc.rotEq2.SetAxisA(t2)
  58. hc.rotEq1.SetAxisB(worldAxisB)
  59. hc.rotEq2.SetAxisB(worldAxisB)
  60. if hc.motorEq.Enabled() {
  61. hc.motorEq.SetAxisA(hc.axisA.Clone().ApplyQuaternion(quatA))
  62. hc.motorEq.SetAxisB(hc.axisB.Clone().ApplyQuaternion(quatB))
  63. }
  64. }