API Docs for:

File: /home/lindsay/xeolabs/xeogl-next/xeogl/src/geometry/boxGeometry.js

/**
 A **BoxGeometry** is a parameterized {{#crossLink "Geometry"}}{{/crossLink}} that defines a box-shaped mesh for attached {{#crossLink "Mesh"}}Meshes{{/crossLink}}.

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

 ## Overview

 * Dynamically modify a BoxGeometry's dimensions at any time by updating its {{#crossLink "BoxGeometry/center:property"}}{{/crossLink}}, {{#crossLink "BoxGeometry/xSize:property"}}{{/crossLink}}, {{#crossLink "BoxGeometry/ySize:property"}}{{/crossLink}} and {{#crossLink "BoxGeometry/zSize:property"}}{{/crossLink}} properties.
 * Dynamically switch its primitive type between ````"points"````, ````"lines"```` and ````"triangles"```` at any time by
 updating its {{#crossLink "Geometry/primitive:property"}}{{/crossLink}} property.

 ## Examples

 * [Textured BoxGeometry](../../examples/#geometry_primitives_box)

 ## Usage

 An {{#crossLink "Mesh"}}{{/crossLink}} with a BoxGeometry and a {{#crossLink "PhongMaterial"}}{{/crossLink}} with
 diffuse {{#crossLink "Texture"}}{{/crossLink}}:

 ````javascript
 new xeogl.Mesh({

     geometry: new xeogl.BoxGeometry({
        center: [0,0,0],
        xSize: 1,  // Half-size on each axis; BoxGeometry is actually two units big on each side.
        ySize: 1,
        zSize: 1
     }),

     material: new xeogl.PhongMaterial({
        diffuseMap: new xeogl.Texture({
            src: "textures/diffuse/uvGrid2.jpg"
        })
     })
 });
 ````

 @class BoxGeometry
 @module xeogl
 @submodule geometry
 @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] {*} Configs
 @param [cfg.id] {String} Optional ID, unique among all components in the parent {{#crossLink "Scene"}}Scene{{/crossLink}},
 generated automatically when omitted.
 @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to this BoxGeometry.
 @param [cfg.primitive="triangles"] {String} The primitive type. Accepted values for a BoxGeometry are 'points', 'lines' and 'triangles'.
 @param [cfg.center] {Float32Array} 3D point indicating the center position.
 @param [cfg.xSize=1.0] {Number} Half-size on the X-axis.
 @param [cfg.ySize=1.0] {Number} Half-size on the Y-axis.
 @param [cfg.zSize=1.0] {Number} Half-size on the Z-axis.
 @extends Geometry
 */

import {utils} from '../utils.js';
import {Geometry} from './geometry.js';
import {componentClasses} from "./../componentClasses.js";

const type = "xeogl.BoxGeometry";

class BoxGeometry extends Geometry {

    /**
     JavaScript class name for this Component.

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

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

    init(cfg) {

        let xSize = cfg.xSize || 1;
        if (xSize < 0) {
            this.error("negative xSize not allowed - will invert");
            xSize *= -1;
        }

        let ySize = cfg.ySize || 1;
        if (ySize < 0) {
            this.error("negative ySize not allowed - will invert");
            ySize *= -1;
        }

        let zSize = cfg.zSize || 1;
        if (zSize < 0) {
            this.error("negative zSize not allowed - will invert");
            zSize *= -1;
        }

        const center = cfg.center;
        const centerX = center ? center[0] : 0;
        const centerY = center ? center[1] : 0;
        const centerZ = center ? center[2] : 0;

        const xmin = -xSize + centerX;
        const ymin = -ySize + centerY;
        const zmin = -zSize + centerZ;
        const xmax = xSize + centerX;
        const ymax = ySize + centerY;
        const zmax = zSize + centerZ;

        super.init(utils.apply(cfg, {

            // The vertices - eight for our cube, each
            // one spanning three array elements for X,Y and Z
            positions: [

                // v0-v1-v2-v3 front
                xmax, ymax, zmax,
                xmin, ymax, zmax,
                xmin, ymin, zmax,
                xmax, ymin, zmax,

                // v0-v3-v4-v1 right
                xmax, ymax, zmax,
                xmax, ymin, zmax,
                xmax, ymin, zmin,
                xmax, ymax, zmin,

                // v0-v1-v6-v1 top
                xmax, ymax, zmax,
                xmax, ymax, zmin,
                xmin, ymax, zmin,
                xmin, ymax, zmax,

                // v1-v6-v7-v2 left
                xmin, ymax, zmax,
                xmin, ymax, zmin,
                xmin, ymin, zmin,
                xmin, ymin, zmax,

                // v7-v4-v3-v2 bottom
                xmin, ymin, zmin,
                xmax, ymin, zmin,
                xmax, ymin, zmax,
                xmin, ymin, zmax,

                // v4-v7-v6-v1 back
                xmax, ymin, zmin,
                xmin, ymin, zmin,
                xmin, ymax, zmin,
                xmax, ymax, zmin
            ],

            // Normal vectors, one for each vertex
            normals: [

                // v0-v1-v2-v3 front
                0, 0, 1,
                0, 0, 1,
                0, 0, 1,
                0, 0, 1,

                // v0-v3-v4-v5 right
                1, 0, 0,
                1, 0, 0,
                1, 0, 0,
                1, 0, 0,

                // v0-v5-v6-v1 top
                0, 1, 0,
                0, 1, 0,
                0, 1, 0,
                0, 1, 0,

                // v1-v6-v7-v2 left
                -1, 0, 0,
                -1, 0, 0,
                -1, 0, 0,
                -1, 0, 0,

                // v7-v4-v3-v2 bottom
                0, -1, 0,
                0, -1, 0,
                0, -1, 0,
                0, -1, 0,

                // v4-v7-v6-v5 back
                0, 0, -1,
                0, 0, -1,
                0, 0, -1,
                0, 0, -1
            ],

            // UV coords
            uv: [

                // v0-v1-v2-v3 front
                1, 0,
                0, 0,
                0, 1,
                1, 1,

                // v0-v3-v4-v1 right
                0, 0,
                0, 1,
                1, 1,
                1, 0,

                // v0-v1-v6-v1 top
                1, 1,
                1, 0,
                0, 0,
                0, 1,

                // v1-v6-v7-v2 left
                1, 0,
                0, 0,
                0, 1,
                1, 1,

                // v7-v4-v3-v2 bottom
                0, 1,
                1, 1,
                1, 0,
                0, 0,

                // v4-v7-v6-v1 back
                0, 1,
                1, 1,
                1, 0,
                0, 0
            ],

            // Indices - these organise the
            // positions and uv texture coordinates
            // into geometric primitives in accordance
            // with the "primitive" parameter,
            // in this case a set of three indices
            // for each triangle.
            //
            // Note that each triangle is specified
            // in counter-clockwise winding order.
            //
            // You can specify them in clockwise
            // order if you configure the Modes
            // node's frontFace flag as "cw", instead of
            // the default "ccw".
            indices: [
                0, 1, 2,
                0, 2, 3,
                // front
                4, 5, 6,
                4, 6, 7,
                // right
                8, 9, 10,
                8, 10, 11,
                // top
                12, 13, 14,
                12, 14, 15,
                // left
                16, 17, 18,
                16, 18, 19,
                // bottom
                20, 21, 22,
                20, 22, 23
            ],

            // Tangents are lazy-computed from normals and UVs
            // for Normal mapping once we know we have texture

            tangents: null
        }));

        this.box = true;
    }
}

componentClasses[type] = BoxGeometry;

export{BoxGeometry};