API Docs for:

File: /home/lindsay/xeolabs/xeogl-next/xeogl/examples/js/helpers/planeHelper.js

/**

 Helper that visualizes the position and direction of a plane.

 @class PlaneHelper
 @constructor
 @param cfg {*} Configuration
 @param [cfg.pos=[0,0,0]] {Float32Array} World-space position.
 @param [cfg.dir=[0,0,1]] {Float32Array} World-space direction vector.
 @param [cfg.color=[0.4,0.4,0.4]] {Float32Array} Emmissive color
 @param [cfg.solid=true] {Boolean} Indicates whether or not this helper is filled with color or just wireframe.
 @param [cfg.visible=true] {Boolean} Indicates whether or not this helper is visible.
 @param [cfg.planeSize] {Float32Array} The width and height of the PlaneHelper plane indicator.
 @param [cfg.autoPlaneSize=false] {Boolean} Indicates whether or not this PlaneHelper's
 {{#crossLink "PlaneHelper/planeSize:property"}}{{/crossLink}} is automatically sized to fit within
 the {{#crossLink "Scene/aabb:property"}}Scene's boundary{{/crossLink}}.
 */

{
    const arrowPositions = new Float32Array(6);
    const zeroVec = new Float32Array([0, 0, -1]);
    const quat = new Float32Array(4);

    xeogl.PlaneHelper = class xeoglPlaneHelper extends xeogl.Component {

        init(cfg) {

            super.init(cfg);

            this._solid = false;
            this._visible = false;

            this._group = new xeogl.Group(this, {
                positions: [10, 10, 0],
                backfaces: false,
                clippable: false
            });

            this._planeWire = this._group.addChild(new xeogl.Mesh(this, {
                geometry: new xeogl.Geometry(this, {
                    primitive: "lines",
                    positions: [
                        0.5, 0.5, 0.0, 0.5, -0.5, 0.0, // 0
                        -0.5, -0.5, 0.0, -0.5, 0.5, 0.0, // 1
                        0.5, 0.5, -0.0, 0.5, -0.5, -0.0, // 2
                        -0.5, -0.5, -0.0, -0.5, 0.5, -0.0 // 3
                    ],
                    indices: [0, 1, 0, 3, 1, 2, 2, 3]
                }),
                material: new xeogl.PhongMaterial(this, {
                    emissive: [1, 0, 0],
                    diffuse: [0, 0, 0],
                    lineWidth: 2
                }),
                pickable: false,
                collidable: false,
                clippable: false
            }));

            this._planeSolid = this._group.addChild(new xeogl.Mesh(this, {
                geometry: new xeogl.Geometry(this, {
                    primitive: "triangles",
                    positions: [
                        0.5, 0.5, 0.0, 0.5, -0.5, 0.0, // 0
                        -0.5, -0.5, 0.0, -0.5, 0.5, 0.0, // 1
                        0.5, 0.5, -0.0, 0.5, -0.5, -0.0, // 2
                        -0.5, -0.5, -0.0, -0.5, 0.5, -0.0 // 3
                    ],
                    indices: [0, 1, 2, 2, 3, 0]
                }),
                material: new xeogl.PhongMaterial(this, {
                    emissive: [0, 0, 0],
                    diffuse: [0, 0, 0],
                    specular: [1, 1, 1],
                    shininess: 120,
                    alpha: 0.3,
                    alphaMode: "blend",
                    backfaces: true
                }),
                pickable: false,
                collidable: false,
                clippable: false,
                visible: false
            }));

            this._label = this._group.addChild(new xeogl.Mesh(this, {
                geometry: new xeogl.VectorTextGeometry(this, {
                    text: this.id,
                    size: 0.07,
                    origin: [0.02, 0.02, 0.0]
                }),
                material: new xeogl.PhongMaterial(this, {
                    emissive: [0.3, 1, 0.3],
                    lineWidth: 2
                }),
                pickable: false,
                collidable: false,
                clippable: false,
                billboard: "spherical"
            }));

            this._arrow = new xeogl.Mesh(this, {
                geometry: new xeogl.Geometry(this, {
                    primitive: "lines",
                    positions: [
                        1.0, 1.0, 1.0, 1.0, -1.0, 1.0
                    ],
                    indices: [0, 1]
                }),
                material: new xeogl.PhongMaterial(this, {
                    emissive: [1, 0, 0],
                    diffuse: [0, 0, 0],
                    lineWidth: 4
                }),
                pickable: false,
                collidable: false,
                clippable: false
            });

            this.planeSize = cfg.planeSize;
            this.autoPlaneSize = cfg.autoPlaneSize;
            this.pos = cfg.pos;
            this.dir = cfg.dir;
            this.color = cfg.color;
            this.solid = cfg.solid;
            this.visible = cfg.visible;
        }

        _update() {

            const pos = this._pos;
            const dir = this._dir;

            // Rebuild arrow geometry

            arrowPositions[0] = pos[0];
            arrowPositions[1] = pos[1];
            arrowPositions[2] = pos[2];
            arrowPositions[3] = pos[0] + dir[0];
            arrowPositions[4] = pos[1] + dir[1];
            arrowPositions[5] = pos[2] + dir[2];

            this._arrow.geometry.positions = arrowPositions;
        }

        /**
         * World-space position of this PlaneHelper.
         *
         * @property worldPos
         * @default [0,0,0]
         * @type {Float32Array}
         */
        set pos(value) {
            (this._pos = this._pos || xeogl.math.vec3()).set(value || [0, 0, 0]);
            this._group.position = this._pos;
            this._needUpdate(); // Need to rebuild arrow
        }

        get pos() {
            return this._pos;
        }

        /**
         * World-space direction of this PlaneHelper.
         *
         * @property dir
         * @default [0,0,1]
         * @type {Float32Array}
         */
        set dir(value) {
            (this._dir = this._dir || xeogl.math.vec3()).set(value || [0, 0, 1]);
            xeogl.math.vec3PairToQuaternion(zeroVec, this._dir, quat);
            this._group.quaternion = quat;
            this._needUpdate(); // Need to rebuild arrow
        }

        get dir() {
            return this._dir;
        }

        /**
         * The width and height of the PlaneHelper plane indicator.
         *
         * Values assigned to this property will be overridden by an auto-computed value when
         * {{#crossLink "PlaneHelper/autoPlaneSize:property"}}{{/crossLink}} is true.
         *
         * @property planeSize
         * @default [1,1]
         * @type {Float32Array}
         */
        set planeSize(value) {
            (this._planeSize = this._planeSize || xeogl.math.vec2()).set(value || [1, 1]);
            this._group.scale = [this._planeSize[0], this._planeSize[1], 1.0];
        }

        get planeSize() {
            return this._planeSize;
        }

        /**
         * Indicates whether this PlaneHelper's {{#crossLink "PlaneHelper/planeSize:property"}}{{/crossLink}} is automatically
         * generated or not.
         *
         * When auto-generated, {{#crossLink "PlaneHelper/planeSize:property"}}{{/crossLink}} will automatically size
         * to fit within the {{#crossLink "Scene/aabb:property"}}Scene's boundary{{/crossLink}}.
         *
         * @property autoPlaneSize
         * @default false
         * @type {Boolean}
         */
        set autoPlaneSize(value) {

            value = !!value;

            if (this._autoPlaneSize === value) {
                return;
            }

            this._autoPlaneSize = value;

            if (this._autoPlaneSize) {
                if (!this._onSceneAABB) {
                    this._onSceneAABB = this.scene.on("boundary", function () {
                        const aabbDiag = xeogl.math.getAABB3Diag(this.scene.aabb);
                        const clipSize = (aabbDiag * 0.50);
                        this.planeSize = [clipSize, clipSize];
                    }, this);
                }
            } else {
                if (this._onSceneAABB) {
                    this.scene.off(this._onSceneAABB);
                    this._onSceneAABB = null;
                }
            }
        }

        get color() {
            return this._autoPlaneSize;
        }

        /**
         * Emmissive color of this PlaneHelper.
         *
         * @property color
         * @default [0.4,0.4,0.4]
         * @type {Float32Array}
         */
        set color(value) {
            (this._color = this._color || xeogl.math.vec3()).set(value || [0.4, 0.4, 0.4]);
            this._planeWire.material.emissive = this._color;
            this._arrow.material.emissive = this._color;
        }

        get color() {
            return this._color;
        }

        /**
         Indicates whether this PlaneHelper is filled with color or just wireframe.

         @property solid
         @default true
         @type Boolean
         */
        set solid(value) {
            this._solid = value !== false;
            this._planeSolid.visible = this._solid && this._visible;
        }

        get solid() {
            return this._solid;
        }

        /**
         Indicates whether this PlaneHelper is visible or not.

         @property visible
         @default true
         @type Boolean
         */
        set visible(value) {
            this._visible = value !== false;
            this._planeWire.visible = this._visible;
            this._planeSolid.visible = this._solid && this._visible;
            this._arrow.visible = this._visible;
            this._label.visible = this._visible;
        }

        get visible() {
            return this._visible;
        }

        destroy() {
            super.destroy();
            if (this._onSceneAABB) {
                this.scene.off(this._onSceneAABB);
            }
        }
    };
}