UNPKG

cannon

Version:

A lightweight 3D physics engine written in JavaScript.

135 lines (113 loc) 4.16 kB
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); } };