#

API Docs for: 0.6.0
Show: Inherited Protected Private Deprecated

# File: src/collision/AABB.js

    var Vec3 = require('../math/Vec3');
    var Utils = require('../utils/Utils');

    module.exports = AABB;

    /**
     * Axis aligned bounding box class.
     * @class AABB
     * @constructor
     * @param {Object}  [options]
     * @param {Array}   [options.upperBound]
     * @param {Array}   [options.lowerBound]
     */
    function AABB(options){
        options = options || {};

        /**
         * The lower bound of the bounding box.
         * @property lowerBound
         * @type {Array}
         */
        this.lowerBound = new Vec3();
        if(options.lowerBound){
            this.lowerBound.copy(options.lowerBound);
        }

        /**
         * The upper bound of the bounding box.
         * @property upperBound
         * @type {Array}
         */
        this.upperBound = new Vec3();
        if(options.upperBound){
            this.upperBound.copy(options.upperBound);
        }
    }

    var tmp = new Vec3();

    /**
     * Set the AABB bounds from a set of points.
     * @method setFromPoints
     * @param {Array} points An array of Vec3's.
     * @todo
     */
    AABB.prototype.setFromPoints = function(points, position, quaternion, skinSize){
        var l = this.lowerBound,
            u = this.upperBound,
            q = quaternion;

        // Set to the first point
        l.copy(points[0]);
        if(q){
            q.vmult(l, l);
        }
        u.copy(l);

        for(var i = 1; i<points.length; i++){
            var p = points[i];

            if(q){
                q.vmult(p, tmp);
                p = tmp;
            }

            if(p.x > u.x){ u.x = p.x; }
            if(p.x < l.x){ l.x = p.x; }
            if(p.y > u.y){ u.y = p.y; }
            if(p.y < l.y){ l.y = p.y; }
            if(p.z > u.z){ u.z = p.z; }
            if(p.z < l.z){ l.z = p.z; }
        }

        // Add offset
        if (position) {
            position.vadd(l, l);
            position.vadd(u, u);
        }

        if(skinSize){
            l.x -= skinSize;
            l.y -= skinSize;
            l.z -= skinSize;
            u.x += skinSize;
            u.y += skinSize;
            u.z += skinSize;
        }
    };

    /**
     * Copy bounds from an AABB to this AABB
     * @method copy
     * @param  {AABB} aabb
     */
    AABB.prototype.copy = function(aabb){
        // vectors copy is the other direction... bad!
        this.lowerBound.copy(aabb.lowerBound);
        this.upperBound.copy(aabb.upperBound);
    };

    /**
     * Extend this AABB so that it covers the given AABB too.
     * @method extend
     * @param  {AABB} aabb
     * @todo
     */
    AABB.prototype.extend = function(aabb){
        // Extend lower bound
        var l = aabb.lowerBound.x;
        if(this.lowerBound.x > l){
            this.lowerBound.x = l;
        }

        // Upper
        var u = aabb.upperBound.x;
        if(this.upperBound.x < u){
            this.upperBound.x = u;
        }

        // Extend lower bound
        var l = aabb.lowerBound.y;
        if(this.lowerBound.y > l){
            this.lowerBound.y = l;
        }

        // Upper
        var u = aabb.upperBound.y;
        if(this.upperBound.y < u){
            this.upperBound.y = u;
        }
    };

    /**
     * Returns true if the given AABB overlaps this AABB.
     * @method overlaps
     * @param  {AABB} aabb
     * @return {Boolean}
     */
    AABB.prototype.overlaps = function(aabb){
        var l1 = this.lowerBound,
            u1 = this.upperBound,
            l2 = aabb.lowerBound,
            u2 = aabb.upperBound;

        //      l2        u2
        //      |---------|
        // |--------|
        // l1       u1

        return ((l2.x <= u1.x && u1.x <= u2.x) || (l1.x <= u2.x && u2.x <= u1.x)) &&
               ((l2.y <= u1.y && u1.y <= u2.y) || (l1.y <= u2.y && u2.y <= u1.y));
    };