#

API Docs for: 0.6.1
Show: Inherited Protected Private Deprecated

# File: src/equations/ContactEquation.js

    module.exports = ContactEquation;

    var Equation = require('./Equation');
    var Vec3 = require('../math/Vec3');
    var Mat3 = require('../math/Mat3');

    /**
     * Contact/non-penetration constraint equation
     * @class ContactEquation
     * @constructor
     * @author schteppe
     * @param {Body} bodyA
     * @param {Body} bodyB
     * @extends Equation
     */
    function ContactEquation(bodyA, bodyB, maxForce){
        maxForce = typeof(maxForce) !== 'undefined' ? maxForce : 1e6;
        Equation.call(this, bodyA, bodyB, 0, maxForce);

        /**
         * @property restitution
         * @type {Number}
         */
        this.restitution = 0.0; // "bounciness": u1 = -e*u0

        /**
         * World-oriented vector that goes from the center of bi to the contact point.
         * @property {Vec3} ri
         */
        this.ri = new Vec3();

        /**
         * World-oriented vector that starts in body j position and goes to the contact point.
         * @property {Vec3} rj
         */
        this.rj = new Vec3();

        /**
         * Contact normal, pointing out of body i.
         * @property {Vec3} ni
         */
        this.ni = new Vec3();
    }

    ContactEquation.prototype = new Equation();
    ContactEquation.prototype.constructor = ContactEquation;

    var ContactEquation_computeB_temp1 = new Vec3(); // Temp vectors
    var ContactEquation_computeB_temp2 = new Vec3();
    var ContactEquation_computeB_temp3 = new Vec3();
    ContactEquation.prototype.computeB = function(h){
        var a = this.a,
            b = this.b,
            bi = this.bi,
            bj = this.bj,
            ri = this.ri,
            rj = this.rj,
            rixn = ContactEquation_computeB_temp1,
            rjxn = ContactEquation_computeB_temp2,

            vi = bi.velocity,
            wi = bi.angularVelocity,
            fi = bi.force,
            taui = bi.torque,

            vj = bj.velocity,
            wj = bj.angularVelocity,
            fj = bj.force,
            tauj = bj.torque,

            penetrationVec = ContactEquation_computeB_temp3,

            GA = this.jacobianElementA,
            GB = this.jacobianElementB,

            n = this.ni;

        // Caluclate cross products
        ri.cross(n,rixn);
        rj.cross(n,rjxn);

        // g = xj+rj -(xi+ri)
        // G = [ -ni  -rixn  ni  rjxn ]
        n.negate(GA.spatial);
        rixn.negate(GA.rotational);
        GB.spatial.copy(n);
        GB.rotational.copy(rjxn);

        // Calculate the penetration vector
        penetrationVec.copy(bj.position);
        penetrationVec.vadd(rj,penetrationVec);
        penetrationVec.vsub(bi.position,penetrationVec);
        penetrationVec.vsub(ri,penetrationVec);

        var g = n.dot(penetrationVec);

        // Compute iteration
        var ePlusOne = this.restitution + 1;
        var GW = ePlusOne * vj.dot(n) - ePlusOne * vi.dot(n) + wj.dot(rjxn) - wi.dot(rixn);
        var GiMf = this.computeGiMf();

        var B = - g * a - GW * b - h*GiMf;

        return B;
    };

    var ContactEquation_getImpactVelocityAlongNormal_vi = new Vec3();
    var ContactEquation_getImpactVelocityAlongNormal_vj = new Vec3();
    var ContactEquation_getImpactVelocityAlongNormal_xi = new Vec3();
    var ContactEquation_getImpactVelocityAlongNormal_xj = new Vec3();
    var ContactEquation_getImpactVelocityAlongNormal_relVel = new Vec3();

    /**
     * Get the current relative velocity in the contact point.
     * @method getImpactVelocityAlongNormal
     * @return {number}
     */
    ContactEquation.prototype.getImpactVelocityAlongNormal = function(){
        var vi = ContactEquation_getImpactVelocityAlongNormal_vi;
        var vj = ContactEquation_getImpactVelocityAlongNormal_vj;
        var xi = ContactEquation_getImpactVelocityAlongNormal_xi;
        var xj = ContactEquation_getImpactVelocityAlongNormal_xj;
        var relVel = ContactEquation_getImpactVelocityAlongNormal_relVel;

        this.bi.position.vadd(this.ri, xi);
        this.bj.position.vadd(this.rj, xj);

        this.bi.getVelocityAtWorldPoint(xi, vi);
        this.bj.getVelocityAtWorldPoint(xj, vj);

        vi.vsub(vj, relVel);

        return this.ni.dot(relVel);
    };