File: src/constraints/HingeConstraint.js
module.exports = HingeConstraint;
var Constraint = require('./Constraint');
var PointToPointConstraint = require('./PointToPointConstraint');
var RotationalEquation = require('../equations/RotationalEquation');
var RotationalMotorEquation = require('../equations/RotationalMotorEquation');
var ContactEquation = require('../equations/ContactEquation');
var Vec3 = require('../math/Vec3');
/**
* Hinge constraint. Think of it as a door hinge. It tries to keep the door in the correct place and with the correct orientation.
* @class HingeConstraint
* @constructor
* @author schteppe
* @param {Body} bodyA
* @param {Body} bodyB
* @param {object} [options]
* @param {Vec3} [options.pivotA] A point defined locally in bodyA. This defines the offset of axisA.
* @param {Vec3} [options.axisA] An axis that bodyA can rotate around, defined locally in bodyA.
* @param {Vec3} [options.pivotB]
* @param {Vec3} [options.axisB]
* @param {Number} [options.maxForce=1e6]
* @extends PointToPointConstraint
*/
function HingeConstraint(bodyA, bodyB, options){
options = options || {};
var maxForce = typeof(options.maxForce) !== 'undefined' ? options.maxForce : 1e6;
var pivotA = options.pivotA ? options.pivotA.clone() : new Vec3();
var pivotB = options.pivotB ? options.pivotB.clone() : new Vec3();
PointToPointConstraint.call(this, bodyA, pivotA, bodyB, pivotB, maxForce);
/**
* Rotation axis, defined locally in bodyA.
* @property {Vec3} axisA
*/
var axisA = this.axisA = options.axisA ? options.axisA.clone() : new Vec3(1,0,0);
axisA.normalize();
/**
* Rotation axis, defined locally in bodyB.
* @property {Vec3} axisB
*/
var axisB = this.axisB = options.axisB ? options.axisB.clone() : new Vec3(1,0,0);
axisB.normalize();
/**
* @property {RotationalEquation} rotationalEquation1
*/
var r1 = this.rotationalEquation1 = new RotationalEquation(bodyA,bodyB,options);
/**
* @property {RotationalEquation} rotationalEquation2
*/
var r2 = this.rotationalEquation2 = new RotationalEquation(bodyA,bodyB,options);
/**
* @property {RotationalMotorEquation} motorEquation
*/
var motor = this.motorEquation = new RotationalMotorEquation(bodyA,bodyB,maxForce);
motor.enabled = false; // Not enabled by default
// Equations to be fed to the solver
this.equations.push(
r1, // rotational1
r2, // rotational2
motor
);
}
HingeConstraint.prototype = new PointToPointConstraint();
HingeConstraint.constructor = HingeConstraint;
/**
* @method enableMotor
*/
HingeConstraint.prototype.enableMotor = function(){
this.motorEquation.enabled = true;
};
/**
* @method disableMotor
*/
HingeConstraint.prototype.disableMotor = function(){
this.motorEquation.enabled = false;
};
/**
* @method setMotorSpeed
* @param {number} speed
*/
HingeConstraint.prototype.setMotorSpeed = function(speed){
this.motorEquation.targetVelocity = speed;
};
/**
* @method setMotorMaxForce
* @param {number} maxForce
*/
HingeConstraint.prototype.setMotorMaxForce = function(maxForce){
this.motorEquation.maxForce = maxForce;
this.motorEquation.minForce = -maxForce;
};
var HingeConstraint_update_tmpVec1 = new Vec3();
var HingeConstraint_update_tmpVec2 = new Vec3();
HingeConstraint.prototype.update = function(){
var bodyA = this.bodyA,
bodyB = this.bodyB,
motor = this.motorEquation,
r1 = this.rotationalEquation1,
r2 = this.rotationalEquation2,
worldAxisA = HingeConstraint_update_tmpVec1,
worldAxisB = HingeConstraint_update_tmpVec2;
var axisA = this.axisA;
var axisB = this.axisB;
PointToPointConstraint.prototype.update.call(this);
// Get world axes
bodyA.quaternion.vmult(axisA, worldAxisA);
bodyB.quaternion.vmult(axisB, worldAxisB);
worldAxisA.tangents(r1.axisA, r2.axisA);
r1.axisB.copy(worldAxisB);
r2.axisB.copy(worldAxisB);
if(this.motorEquation.enabled){
bodyA.quaternion.vmult(this.axisA, motor.axisA);
bodyB.quaternion.vmult(this.axisB, motor.axisB);
}
};