API Docs for:

File: /home/lindsay/xeolabs/xeogl-next/xeogl/src/clipping/clip.js

/**
 A **Clip** is an arbitrarily-aligned World-space clipping plane.

 <a href="../../examples/#effects_clipping"><img src="../../../assets/images/screenshots/Clips.png"></img></a>

 ## Overview

 * Used to slice portions off objects, to create cross-section views or reveal interiors.
 * Is contained within a {{#crossLink "Clips"}}{{/crossLink}} belonging to its {{#crossLink "Scene"}}{{/crossLink}}.
 * Has a World-space position in {{#crossLink "Clip/pos:property"}}{{/crossLink}} and orientation in {{#crossLink "Clip/dir:property"}}{{/crossLink}}.
 * Discards elements from the half-space in the direction of {{#crossLink "Clip/dir:property"}}{{/crossLink}}.
 * Can be be enabled or disabled via its {{#crossLink "Clip/active:property"}}{{/crossLink}} property.

 ## Usage

 In the example below, we have an {{#crossLink "Mesh"}}{{/crossLink}} that's attached by a {{#crossLink "Clips"}}{{/crossLink}}
 that contains two {{#crossLink "Clip"}}{{/crossLink}} components.  The first {{#crossLink "Clip"}}{{/crossLink}} is on the
 positive diagonal, while the second is on the negative diagonal. The {{#crossLink "Mesh"}}Mesh's{{/crossLink}} {{#crossLink "Geometry"}}{{/crossLink}}
 is a box, which will get two of its corners clipped off.

 ````javascript
 // Create a set of Clip planes in the default Scene
 scene.clips.clips = [

 // Clip plane on negative diagonal
 new xeogl.Clip({
         pos: [1.0, 1.0, 1.0],
         dir: [-1.0, -1.0, -1.0],
         active: true
     }),

 // Clip plane on positive diagonal
 new xeogl.Clip({
         pos: [-1.0, -1.0, -1.0],
         dir: [1.0, 1.0, 1.0],
         active: true
     })
 ];

 // Create a Mesh in the default Scene, that will be clipped by our Clip planes
 var mesh = new xeogl.Mesh({
     geometry: new xeogl.SphereGeometry(),
     clippable: true // Enable clipping (default)
 });
 ````

 ### Switching clipping on and off for a Mesh

 An {{#crossLink "Mesh"}}{{/crossLink}}'s {{#crossLink "Mesh/clippable:property"}}{{/crossLink}} property indicates
 whether or not it is affected by Clip components.

 You can switch it at any time, like this:

 ```` javascript
 // Disable clipping for the Mesh
 mesh.clippable = false;

 // Enable clipping for the Mesh
 mesh.clippable = true;
 ````

 @class Clip
 @module xeogl
 @submodule clipping
 @constructor
 @param [owner] {Component} Owner component. When destroyed, the owner will destroy this component as well. Creates this component within the default {{#crossLink "Scene"}}{{/crossLink}} when omitted.
 @param [cfg] {*} Clip configuration
 @param [cfg.id] {String} Optional ID, unique among all components in the parent {{#crossLink "Scene"}}Scene{{/crossLink}}, generated automatically when omitted.
 You only need to supply an ID if you need to be able to find the Clip by ID within the {{#crossLink "Scene"}}Scene{{/crossLink}}.
 @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to this Clip.
 @param [cfg.active=true] {Boolean} Indicates whether or not this Clip is active.
 @param [cfg.pos=[0,0,0]] {Array of Number} World-space position of the clipping plane.
 @param [cfg.dir=[0,0 -1]] {Array of Number} Vector perpendicular to the plane surface, indicating its orientation.
 @extends Component
 */
import {Component} from '../component.js';
import {State} from '../renderer/state.js';
import {componentClasses} from "./../componentClasses.js";

const type = "xeogl.Clip";

class Clip extends Component {

    /**
     JavaScript class name for this Component.

     For example: "xeogl.AmbientLight", "xeogl.MetallicMaterial" etc.

     @property type
     @type String
     @final
     */
    get type() {
        return type;
    }

    init(cfg) {

        super.init(cfg);

        this._state = new State({
            active: true,
            pos: new Float32Array(3),
            dir: new Float32Array(3)
        });

        this.active = cfg.active;
        this.pos = cfg.pos;
        this.dir = cfg.dir;

        this.scene._clipCreated(this);
    }

    /**
     Indicates whether this Clip is active or not.

     @property active
     @default true
     @type Boolean
     */
    set active(value) {
        this._state.active = value !== false;
        this._renderer.imageDirty();
        /**
         Fired whenever this Clip's {{#crossLink "Clip/active:property"}}{{/crossLink}} property changes.

         @event active
         @param value {Boolean} The property's new value
         */
        this.fire("active", this._state.active);
    }

    get active() {
        return this._state.active;
    }

    /**
     The World-space position of this Clip's plane.

     @property pos
     @default [0, 0, 0]
     @type Float32Array
     */
    set pos(value) {
        this._state.pos.set(value || [0, 0, 0]);
        this._renderer.imageDirty();
        /**
         Fired whenever this Clip's {{#crossLink "Clip/pos:property"}}{{/crossLink}} property changes.

         @event pos
         @param value Float32Array The property's new value
         */
        this.fire("pos", this._state.pos);
    }

    get pos() {
        return this._state.pos;
    }

    /**
     Vector indicating the orientation of this Clip plane.

     The vector originates at {{#crossLink "Clip/pos:property"}}{{/crossLink}}. Elements on the
     same side of the vector are clipped.

     @property dir
     @default [0, 0, -1]
     @type Float32Array
     */
    set dir(value) {
        this._state.dir.set(value || [0, 0, -1]);
        this._renderer.imageDirty();
        /**
         Fired whenever this Clip's {{#crossLink "Clip/dir:property"}}{{/crossLink}} property changes.

         @event dir
         @param value {Float32Array} The property's new value
         */
        this.fire("dir", this._state.dir);
    }

    get dir() {
        return this._state.dir;
    }

    destroy() {
        this._state.destroy();
        this.scene._clipDestroyed(this);
        super.destroy();
    }
}

componentClasses[type] = Clip;

export{Clip};