| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- // Copyright 2016 The G3N Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package constraint
- import (
- "github.com/g3n/engine/physics/equation"
- "github.com/g3n/engine/math32"
- )
- // Lock constraint.
- // Removes all degrees of freedom between the bodies.
- type Lock struct {
- PointToPoint
- rotEq1 *equation.Rotational
- rotEq2 *equation.Rotational
- rotEq3 *equation.Rotational
- xA *math32.Vector3
- xB *math32.Vector3
- yA *math32.Vector3
- yB *math32.Vector3
- zA *math32.Vector3
- zB *math32.Vector3
- }
- // NewLock creates and returns a pointer to a new Lock constraint object.
- func NewLock(bodyA, bodyB IBody, maxForce float32) *Lock {
- lc := new(Lock)
- // Set pivot point in between
- posA := bodyA.Position()
- posB := bodyB.Position()
- halfWay := math32.NewVec3().AddVectors(&posA, &posB)
- halfWay.MultiplyScalar(0.5)
- pivotB := bodyB.PointToLocal(halfWay)
- pivotA := bodyA.PointToLocal(halfWay)
- // The point-to-point constraint will keep a point shared between the bodies
- lc.initialize(bodyA, bodyB, &pivotA, &pivotB, maxForce)
- // Store initial rotation of the bodies as unit vectors in the local body spaces
- UnitX := math32.NewVector3(1,0,0)
- localA := bodyA.VectorToLocal(UnitX)
- localB := bodyB.VectorToLocal(UnitX)
- lc.xA = &localA
- lc.xB = &localB
- lc.yA = &localA
- lc.yB = &localB
- lc.zA = &localA
- lc.zB = &localB
- // ...and the following rotational equations will keep all rotational DOF's in place
- lc.rotEq1 = equation.NewRotational(bodyA, bodyB, maxForce)
- lc.rotEq2 = equation.NewRotational(bodyA, bodyB, maxForce)
- lc.rotEq3 = equation.NewRotational(bodyA, bodyB, maxForce)
- lc.AddEquation(lc.rotEq1)
- lc.AddEquation(lc.rotEq2)
- lc.AddEquation(lc.rotEq3)
- return lc
- }
- // Update updates the equations with data.
- func (lc *Lock) Update() {
- lc.PointToPoint.Update()
- // These vector pairs must be orthogonal
- xAw := lc.bodyA.VectorToWorld(lc.xA)
- yBw := lc.bodyA.VectorToWorld(lc.yB)
- yAw := lc.bodyA.VectorToWorld(lc.yA)
- zBw := lc.bodyB.VectorToWorld(lc.zB)
- zAw := lc.bodyA.VectorToWorld(lc.zA)
- xBw := lc.bodyB.VectorToWorld(lc.xB)
- lc.rotEq1.SetAxisA(&xAw)
- lc.rotEq1.SetAxisB(&yBw)
- lc.rotEq2.SetAxisA(&yAw)
- lc.rotEq2.SetAxisB(&zBw)
- lc.rotEq3.SetAxisA(&zAw)
- lc.rotEq3.SetAxisB(&xBw)
- }
|